基于mall4j产品的二开项目后端
lee
2024-12-19 0ea1c5ac5452d7373f23139b8b69fc8c792bde2e
init
331 files added
26072 ■■■■■ changed files
README.en.md 36 ●●●●● patch | view | raw | blame | history
pom.xml 335 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-api/pom.xml 21 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-api/src/main/java/com/yami/shop/sys/api/adapter/ApiSignAuthAdapter.java 32 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-api/src/main/java/com/yami/shop/sys/api/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-api/src/main/java/com/yami/shop/sys/api/controller/SysConfigController.java 171 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/pom.xml 21 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/constant/MenuType.java 39 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopEmployeeMapper.java 66 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopEmployeeRoleMapper.java 64 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopMenuMapper.java 114 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopRoleMapper.java 38 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopRoleMenuMapper.java 48 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysLogMapper.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysMenuMapper.java 121 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysRoleMapper.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysRoleMenuMapper.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysUserMapper.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysUserRoleMapper.java 54 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/listener/PermissionErrorHandleListener.java 60 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/listener/ShopEmployeeSuperAdminListener.java 109 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopEmployee.java 93 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopEmployeeRole.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopMenu.java 100 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopRole.java 70 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopRoleMenu.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysLog.java 55 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysMenu.java 81 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysRole.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysRoleMenu.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysUser.java 85 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysUserRole.java 39 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopEmployeeRoleService.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopEmployeeService.java 137 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopMenuService.java 93 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopRoleMenuService.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopRoleService.java 51 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysLogService.java 23 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysMenuService.java 83 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysRoleService.java 49 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysUserService.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopEmployeeRoleServiceImpl.java 29 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopEmployeeServiceImpl.java 291 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopMenuServiceImpl.java 166 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopRoleMenuServiceImpl.java 29 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopRoleServiceImpl.java 103 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysLogServiceImpl.java 27 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysMenuServiceImpl.java 129 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysRoleServiceImpl.java 101 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysUserServiceImpl.java 88 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopEmployeeMapper.xml 58 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopEmployeeRoleMapper.xml 41 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopMenuMapper.xml 113 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopRoleMapper.xml 24 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopRoleMenuMapper.xml 28 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysLogMapper.xml 7 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysMenuMapper.xml 92 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysRoleMapper.xml 17 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysRoleMenuMapper.xml 23 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysUserMapper.xml 17 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysUserRoleMapper.xml 30 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-multishop/pom.xml 26 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/adapter/MultishopSignAuthAdapter.java 63 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/ShopEmployeeController.java 269 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/ShopMenuController.java 133 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/ShopRoleController.java 157 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/SysConfigController.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/pom.xml 27 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/adapter/PlatformSignAuthAdapter.java 83 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/aspect/SysLogAspect.java 91 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/ShopMenuController.java 208 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysAccessKeyController.java 125 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysConfigController.java 106 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysLogController.java 57 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysMenuController.java 224 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysPconfigController.java 86 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysRoleController.java 125 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysUpgradeInfoController.java 122 ●●●●● patch | view | raw | blame | history
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysUserController.java 231 ●●●●● patch | view | raw | blame | history
yami-shop-task/pom.xml 43 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/pom.xml 39 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/config/QRConfig.java 27 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/config/SwaggerConfiguration.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/config/Zxing.java 59 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/PTaskAppController.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/QrCodeController.java 92 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskAppController.java 98 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskCallBackService.java 110 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskController.java 389 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskFinishConditionController.java 81 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskReleaseController.java 76 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskUserBindController.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/pom.xml 35 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/TaskInfoDto.java 12 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/bean/TaskFeaturedFirstScore.java 14 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/bean/TaskManage.java 17 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskAccomplishConditionMapper.java 31 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskClickLogMapper.java 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskCommissionLogMapper.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskDetailMapper.java 39 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskInviteLogMapper.java 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskMapper.java 25 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskProvideRecordMapper.java 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskProvideUserMapper.java 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskRateMapper.java 25 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskRefreshLogMapper.java 20 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskRuleMapper.java 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskSignInCommissionMapper.java 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskSignInLogMapper.java 33 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskUserMapper.java 20 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskUserRelationMapper.java 23 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/Task.java 112 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskAccomplishCondition.java 67 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskAppRelease.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskClickLog.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskCommissionLog.java 57 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskDetail.java 143 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskInviteLog.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskProvideRecord.java 85 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskProvideUser.java 77 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskRate.java 58 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskRefreshLog.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskRule.java 119 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskSignInCommission.java 94 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskSignInLog.java 65 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskUser.java 87 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskUserRelation.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/CommissionGrantLogParam.java 21 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/TaskAccomplishConditionParam.java 16 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/TaskDetailParam.java 33 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/TaskSignInParam.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskAccomplishConditionService.java 33 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskClickLogService.java 13 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskCommissionLogService.java 25 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskDetailService.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskInviteLogService.java 12 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskProvideRecordService.java 13 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskProvideUserService.java 13 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskRateService.java 26 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskRefreshLogService.java 14 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskRuleService.java 25 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskService.java 26 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskSignInCommissionService.java 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskSignInLogService.java 32 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskUserRelationService.java 14 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskUserService.java 26 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskAccomplishConditionServiceImpl.java 76 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskClickLogServiceImpl.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskCommissionLogServiceImpl.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskDetailServiceImpl.java 45 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskInviteLogServiceImpl.java 21 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskProvideRecordServiceImpl.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskProvideUserServiceImpl.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskRateServiceImpl.java 63 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskRefreshLogServiceImpl.java 28 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskRuleServiceImpl.java 101 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskServiceImpl.java 215 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskSignInCommissionServiceImpl.java 31 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskSignInLogServiceImpl.java 154 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskUserRelationServiceImpl.java 29 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskUserServiceImpl.java 144 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskIncomeVO.java 26 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskReleaseVO.java 72 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskRuleVO.java 81 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskVO.java 107 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskAccomplishConditionMapper.xml 64 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskClickLogMapper.xml 18 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskCommissionLogMapper.xml 33 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskDetailMapper.xml 115 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskInviteLogMapper.xml 19 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskMapper.xml 64 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskProvideRecordMapper.xml 23 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskProvideUserMapper.xml 23 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskRateMapper.xml 34 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskRefreshLogMapper.xml 22 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskRuleMapper.xml 31 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskSignInCommissionMapper.xml 28 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskSignInLogMapper.xml 36 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskUserMapper.xml 25 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskUserRelationMapper.xml 17 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-platform/pom.xml 33 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/config/SwaggerConfiguration.java 35 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/controller/TaskController.java 137 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/controller/TaskRateController.java 80 ●●●●● patch | view | raw | blame | history
yami-shop-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/controller/TaskReleaseController.java 127 ●●●●● patch | view | raw | blame | history
yami-shop-user/pom.xml 26 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/pom.xml 34 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/ScoreOrderController.java 167 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserBalanceController.java 75 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserBalanceLogController.java 55 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserLevelController.java 112 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserScoreController.java 224 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BalancePayListener.java 127 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BeanPayListener.java 110 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BlueBalancePayListener.java 143 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BluePointPayListener.java 119 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BlueRedPayListener.java 143 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/LevelUpListener.java 83 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/RedPayListener.java 119 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/SubmitOrderListener.java 123 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/UpdateUserScoreListener.java 79 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/manager/impl/OrderUseScoreManagerImpl.java 302 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/manager/impl/UserLevelOrderManagerImpl.java 180 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/pom.xml 21 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserBalanceCouponMapper.java 46 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserBalanceLogMapper.java 146 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserBalanceMapper.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserGrowthLogMapper.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelCategoryMapper.java 46 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelCouponMapper.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelLogMapper.java 127 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelMapper.java 77 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelRightsMapper.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserRightsMapper.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserScoreDetailMapper.java 88 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserScoreLockMapper.java 54 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserScoreLogMapper.java 55 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserTagMapper.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserTagUserMapper.java 57 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/LevelDetailDto.java 137 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/LevelDto.java 94 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/ScoreDataDto.java 99 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/ScoreOrderMergerDto.java 68 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserBalanceDto.java 68 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserBalanceLogDto.java 50 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserLevelDto.java 106 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserRightsDto.java 63 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserTagDto.java 297 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/enums/GrowthLogSourceEnum.java 69 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/enums/UserRightsInfo.java 49 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/BalanceCouponListener.java 39 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/BalanceRefundListener.java 91 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/CancelOrderListener.java 58 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/CheckIsMainShopListener.java 59 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/OrderRefundListener.java 213 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/PaySuccessOrderListener.java 54 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/ReceiptOrderListener.java 179 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/UserDataListener.java 84 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/UserDestroyListener.java 80 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/UserRegisterLogListener.java 174 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/Coupon.java 113 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserBalance.java 68 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserBalanceCoupon.java 45 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserBalanceLog.java 73 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserGrowthLog.java 72 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevel.java 125 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelCategory.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelCoupon.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelLog.java 114 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelRights.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserRights.java 54 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserScoreDetail.java 64 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserScoreLock.java 48 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserScoreLog.java 83 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserTag.java 153 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserTagUser.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/ScoreOrderService.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserBalanceCouponService.java 60 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserBalanceLogService.java 40 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserBalanceService.java 94 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserGrowthLogService.java 41 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelCategoryService.java 45 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelCouponService.java 46 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelLogService.java 64 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelRightsService.java 36 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelService.java 141 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserMemberService.java 38 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserRightsService.java 47 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserScoreDetailService.java 101 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserScoreLockService.java 37 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserScoreLogService.java 55 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserTagService.java 104 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserTagUserService.java 58 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/ScoreOrderServiceImpl.java 361 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserBalanceCouponServiceImpl.java 63 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserBalanceLogServiceImpl.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserBalanceServiceImpl.java 314 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserGrowthLogServiceImpl.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelCategoryServiceImpl.java 48 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelCouponServiceImpl.java 51 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelLogServiceImpl.java 186 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelRightsServiceImpl.java 42 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelServiceImpl.java 848 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserMenberServiceImpl.java 481 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserRightsServiceImpl.java 56 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserScoreDetailServiceImpl.java 231 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserScoreLockServiceImpl.java 261 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserScoreLogServiceImpl.java 63 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserTagServiceImpl.java 701 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserTagUserServiceImpl.java 65 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/task/ListCustomerExportDataTask.java 22 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/util/CategoryScale.java 69 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/ScoreDetailMapper.xml 58 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserBalanceCouponMapper.xml 30 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserBalanceLogMapper.xml 138 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserBalanceMapper.xml 39 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserGrowthLogMapper.xml 37 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelCategoryMapper.xml 26 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelCouponMapper.xml 28 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelLogMapper.xml 138 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelMapper.xml 131 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelRightsMapper.xml 19 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserRightsMapper.xml 22 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserScoreLockMapper.xml 39 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserScoreLogMapper.xml 60 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserTagMapper.xml 55 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserTagUserMapper.xml 29 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-multishop/pom.xml 29 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-multishop/src/main/java/com/yami/shop/user/multishop/controller/UserMemberController.java 70 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-multishop/src/main/java/com/yami/shop/user/multishop/task/ListCustomerExportDataTask.java 27 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/pom.xml 34 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/config/SwaggerConfiguration.java 34 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/GrowthConfigController.java 82 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreConfigController.java 101 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreDeliveryController.java 43 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreExpireConfigController.java 86 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreOrderController.java 192 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreOtherConfigController.java 82 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserBalanceController.java 107 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserExtensionController.java 80 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserGrowthLogController.java 98 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserLevelCategoryController.java 91 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserLevelController.java 107 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserLevelLogController.java 89 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserRightsController.java 151 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserScoreLogController.java 83 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserTagController.java 149 ●●●●● patch | view | raw | blame | history
yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/task/ScoreTask.java 100 ●●●●● patch | view | raw | blame | history
README.en.md
New file
@@ -0,0 +1,36 @@
# marsrate
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1.  xxxx
2.  xxxx
3.  xxxx
#### Instructions
1.  xxxx
2.  xxxx
3.  xxxx
#### Contribution
1.  Fork the repository
2.  Create Feat_xxx branch
3.  Commit your code
4.  Create Pull Request
#### Gitee Feature
1.  You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2.  Gitee blog [blog.gitee.com](https://blog.gitee.com)
3.  Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4.  The most valuable open source project [GVP](https://gitee.com/gvp)
5.  The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6.  The most popular members  [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
pom.xml
New file
@@ -0,0 +1,335 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.yami.shop</groupId>
    <artifactId>yami-shop</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>yami-shop-sys</module>
        <module>yami-shop-common</module>
        <module>yami-shop-api</module>
        <module>yami-shop-bean</module>
        <module>yami-shop-service</module>
        <module>yami-shop-security</module>
        <module>yami-shop-discount</module>
        <module>yami-shop-coupon</module>
        <module>yami-shop-mp</module>
        <module>yami-shop-distribution</module>
        <module>yami-shop-groupbuy</module>
        <module>yami-shop-seckill</module>
        <module>yami-shop-user</module>
        <module>yami-shop-multishop</module>
        <module>yami-shop-platform</module>
        <module>yami-shop-delivery</module>
        <module>yami-shop-live</module>
        <module>yami-shop-im</module>
        <module>yami-shop-search</module>
        <module>yami-shop-combo</module>
        <module>yami-shop-task</module>
        <module>system-test</module>
        <module>yami-shop-cps</module>
        <module>yami-shop-cdn</module>
        <module>yami-shop-task/yami-shop-task-platform</module>
        <module>system-im-client</module>
        <module>xxl-job</module>
    </modules>
    <properties>
        <yami.shop.version>0.0.1-SNAPSHOT</yami.shop.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEnc2oding>UTF-8</project.reporting.outputEnc2oding>
        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
        <maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
        <spring-boot.version>2.7.7</spring-boot.version>
        <java.version>1.8</java.version>
        <guava.version>31.1-jre</guava.version>
        <hutool.version>5.8.11</hutool.version>
        <poi.version>5.2.3</poi.version>
        <qiniu.version>7.12.1</qiniu.version>
        <qcloud.version>5.6.129</qcloud.version>
        <weixin.version>4.4.0</weixin.version>
        <orika.version>1.5.4</orika.version>
        <aliyun-core.version>4.6.3</aliyun-core.version>
        <alipay.version>4.35.37.ALL</alipay.version>
        <alioss.version>3.16.0</alioss.version>
        <fastjson.version>1.2.83</fastjson.version>
        <mybatis-plus.version>3.4.3</mybatis-plus.version>
        <redisson.version>3.17.7</redisson.version>
        <paypal.version>1.14.0</paypal.version>
        <paypal.v2.version>1.0.5</paypal.v2.version>
        <elasticsearch.version>7.17.5</elasticsearch.version>
        <transmittable-thread-local.version>2.14.2</transmittable-thread-local.version>
        <minio.version>8.4.1</minio.version>
        <xxl-job.version>2.3.1</xxl-job.version>
        <spring-cloud-commons.version>3.1.1</spring-cloud-commons.version>
        <log4j.version>2.19.0</log4j.version>
        <okhttp.version>4.9.3</okhttp.version>
        <knife4j.version>4.0.0</knife4j.version>
        <ip2region.version>2.6.6</ip2region.version>
        <captcha.version>1.3.0</captcha.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-dependencies</artifactId>
                <version>${knife4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-pay</artifactId>
                <version>${weixin.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-miniapp</artifactId>
                <version>${weixin.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-mp</artifactId>
                <version>${weixin.version}</version>
            </dependency>
            <dependency>
                <groupId>ma.glasnost.orika</groupId>
                <artifactId>orika-core</artifactId>
                <version>${orika.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-core</artifactId>
                <version>${aliyun-core.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alipay.sdk</groupId>
                <artifactId>alipay-sdk-java</artifactId>
                <version>${alipay.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${alioss.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <dependency>
                <groupId>io.minio</groupId>
                <artifactId>minio</artifactId>
                <version>${minio.version}</version>
            </dependency>
            <dependency>
                <groupId>com.paypal.sdk</groupId>
                <artifactId>rest-api-sdk</artifactId>
                <version>${paypal.version}</version>
            </dependency>
            <dependency>
                <groupId>com.paypal.sdk</groupId>
                <artifactId>checkout-sdk</artifactId>
                <version>${paypal.v2.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>com.qiniu</groupId>
                <artifactId>qiniu-java-sdk</artifactId>
                <version>${qiniu.version}</version>
            </dependency>
            <dependency>
                <groupId>com.qcloud</groupId>
                <artifactId>cos_api</artifactId>
                <version>${qcloud.version}</version>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
            <!-- 使用redisson集成分布式锁等 -->
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson-spring-boot-starter</artifactId>
                <version>${redisson.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>transmittable-thread-local</artifactId>
                <version>${transmittable-thread-local.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xuxueli</groupId>
                <artifactId>xxl-job-core</artifactId>
                <version>${xxl-job.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-commons</artifactId>
                <version>${spring-cloud-commons.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-to-slf4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp.version}</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <version>${elasticsearch.version}</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>${elasticsearch.version}</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-client</artifactId>
                <version>${elasticsearch.version}</version>
                <exclusions>
                    <exclusion>
                        <artifactId>commons-logging</artifactId>
                        <groupId>commons-logging</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.lionsoul</groupId>
                <artifactId>ip2region</artifactId>
                <version>${ip2region.version}</version>
            </dependency>
            <dependency>
                <groupId>com.anji-plus</groupId>
                <artifactId>captcha</artifactId>
                <version>${captcha.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.6.9</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>${maven-resources-plugin.version}</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <layers>
                        <enabled>true</enabled>
                    </layers>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>
yami-shop-sys/yami-shop-sys-api/pom.xml
New file
@@ -0,0 +1,21 @@
<?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-sys</artifactId>
        <groupId>com.yami.shop</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-sys-api</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-sys-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-sys/yami-shop-sys-api/src/main/java/com/yami/shop/sys/api/adapter/ApiSignAuthAdapter.java
New file
@@ -0,0 +1,32 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.api.adapter;
import com.yami.shop.security.common.adapter.SignAuthAdapter;
import com.yami.shop.security.common.bo.UserInfoInTokenBO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
 *
 * @author lgh on 2018/09/07.
 */
@Service
@AllArgsConstructor
public class ApiSignAuthAdapter implements SignAuthAdapter {
    @Override
    public UserInfoInTokenBO loadUserInfoInToken(Map<String, Object> dataMap) {
        return null;
    }
}
yami-shop-sys/yami-shop-sys-api/src/main/java/com/yami/shop/sys/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.sys.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("sysSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi sysRestApi() {
        return GroupedOpenApi.builder()
                .group("系统配置")
                .packagesToScan("com.yami.shop.sys.api.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-sys/yami-shop-sys-api/src/main/java/com/yami/shop/sys/api/controller/SysConfigController.java
New file
@@ -0,0 +1,171 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.api.controller;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.yami.shop.bean.vo.SysLangVo;
import com.yami.shop.common.bean.SysPayConfig;
import com.yami.shop.common.bean.SysServiceConfig;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.i18n.LanguageEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.service.CdnConfigService;
import com.yami.shop.service.PayInfoService;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
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.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.Objects;
/**
 * 系统配置信息
 * @author yami
 */
@RestController
@Tag(name = "系统配置信息")
@RequestMapping("/sys/config")
@AllArgsConstructor
public class SysConfigController {
    private  final  SysConfigService sysConfigService;
    private  final CdnConfigService cdnConfigService;
    private  final PayInfoService payInfoService;
    @Operation(summary = "获取服务条款信息" , description = "获取服务条款信息")
    @GetMapping("/info/serviceTerms")
    public ServerResponseEntity<String> serviceTerms(){
        Integer dbLang = I18nMessage.getDbLang();
        if(Objects.equals(LanguageEnum.LANGUAGE_EN.getLang(), dbLang)) {
            return ServerResponseEntity.success(sysConfigService.getValue("SERVICE_TERMS_CONFIG_EN"));
        }
        return ServerResponseEntity.success(sysConfigService.getValue("SERVICE_TERMS_CONFIG_CN"));
    }
    @Operation(summary = "获取公共系统配置参数" , description = "获取公共系统配置参数")
    @GetMapping("/sysConfigSwitch")
    public ServerResponseEntity<String> sysConfigSwitch(@RequestParam(value = "key") String key){
        if(key.indexOf("PUBLIC_") > -1) {
            Integer dbLang = I18nMessage.getDbLang();
            key = key.replace("PUBLIC_", "");
            if(Objects.equals(LanguageEnum.LANGUAGE_EN.getLang(), dbLang)) {
                return ServerResponseEntity.success(sysConfigService.getValue(key));
            }
            System.out.println(sysConfigService.getValue(key));
            return ServerResponseEntity.success(sysConfigService.getValue(key));
        }else{
            return ServerResponseEntity.success();
        }
    }
    @Operation(summary = "获取隐私策略信息" , description = "获取隐私策略信息")
    @GetMapping("/info/servicePolicy")
    public ServerResponseEntity<String> servicePolicy(){
        Integer dbLang = I18nMessage.getDbLang();
        if(Objects.equals(LanguageEnum.LANGUAGE_ZH_CN.getLang(), dbLang)) {
            return ServerResponseEntity.success(sysConfigService.getValue("SERVICE_POLICY_CONFIG_CN"));
        }
        return ServerResponseEntity.success(sysConfigService.getValue("SERVICE_POLICY_CONFIG_EN"));
    }
    @Operation(summary = "获取系统支付开关" , description = "获取系统支付开关")
    @GetMapping("/info/getSysPaySwitch")
    public ServerResponseEntity<SysPayConfig> getSysPaySwitch(@RequestParam(value = "mold") String mold){
        String s = sysConfigService.getValue(Constant.PAY_SWITCH_CONFIG);
        SysPayConfig sysPayConfig = JSONObject.parseObject(s,SysPayConfig.class);
//        SysPayConfig sysPayConfig = sysConfigService.getSysConfigObject(Constant.PAY_SWITCH_CONFIG, SysPayConfig.class);
//        String name = cdnConfigService.selectValueByName("balance_pay_day");
//        LocalDate currentDate = LocalDate.now();
//        DayOfWeek dayOfWeek = currentDate.getDayOfWeek();
//        if(sysPayConfig.getBalancePaySwitch()){
//            if(name.indexOf(dayOfWeek.getValue()+"") < 0){
//                sysPayConfig.setBalancePaySwitch(false);
//            }else{
//                String balanceMoney = cdnConfigService.selectValueByName("balance_money");
//                BigDecimal balancePrice = payInfoService.selectMoney(3);
//                if(balancePrice != null){
//                    if(BigDecimal.valueOf(Double.valueOf(balanceMoney)).compareTo(balancePrice) < 0){
//                        sysPayConfig.setBalancePaySwitch(false);
//                    }else{
//                        sysPayConfig.setBalancePaySwitch(true);
//                    }
//                }else{
//                    sysPayConfig.setBalancePaySwitch(true);
//                }
//            }
//        }
//        String sdMoney = cdnConfigService.selectValueByName("sd_money");
//        BigDecimal sdPrice = payInfoService.selectMoney(1);
//        if(sysPayConfig.getSdPayPalSwitch()){
//            if(sdPrice != null){
//                if(BigDecimal.valueOf(Double.valueOf(sdMoney)).compareTo(sdPrice) < 0){
//                    sysPayConfig.setSdQrcodeSwitch(false);
//                    sysPayConfig.setSdPayPalSwitch(false);
//                }else{
//                    sysPayConfig.setSdQrcodeSwitch(true);
//                    sysPayConfig.setSdPayPalSwitch(true);
//                }
//            }else{
//                sysPayConfig.setSdQrcodeSwitch(true);
//                sysPayConfig.setSdPayPalSwitch(true);
//            }
//        }
//        String beanMoney = cdnConfigService.selectValueByName("bean_money");
//        BigDecimal beanPrice = payInfoService.selectMoney(2);
//        if(sysPayConfig.getSdBeanSwitch()){
//            if(beanPrice != null){
//                if(BigDecimal.valueOf(Double.valueOf(beanMoney)).compareTo(beanPrice) < 0){
//                    sysPayConfig.setSdBeanSwitch(false);
//                }else{
//                    sysPayConfig.setSdBeanSwitch(true);
//                }
//            }else{
//                sysPayConfig.setSdBeanSwitch(true);
//            }
//        }
//        if("7".equals(mold) || "8".equals(mold)){
////            sysPayConfig.setBluePointSwitch(false);
//            sysPayConfig.setBlueBalancePointSwitch(false);
//            sysPayConfig.setBlueRedPointSwitch(false);
//        }
        return ServerResponseEntity.success(sysPayConfig);
    }
    @Operation(summary = "获取系统服务条例开关" , description = "获取系统服务条例开关")
    @GetMapping("/info/getSysServiceSwitch")
    public ServerResponseEntity<SysServiceConfig> getSysServiceSwitch(){
        SysServiceConfig sysServiceConfig = sysConfigService.getSysConfigObject(Constant.SERVICE_SWITCH_CONFIG, SysServiceConfig.class);
        return ServerResponseEntity.success(sysServiceConfig);
    }
    @Operation(summary = "获取语言类型" , description = "获取语言类型")
    @GetMapping("/lang")
    public ServerResponseEntity<SysLangVo> getLang(){
        String str = sysConfigService.getValue("LANGUAGE_CONFIG");
        SysLangVo lang = JSONObject.parseObject(str, SysLangVo.class);
        return ServerResponseEntity.success(lang);
    }
}
yami-shop-sys/yami-shop-sys-common/pom.xml
New file
@@ -0,0 +1,21 @@
<?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-sys</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-sys-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-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/constant/MenuType.java
New file
@@ -0,0 +1,39 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.constant;
/**
 * 菜单类型
 * @author yami
 */
public enum MenuType {
    /**
     * 目录
     */
    CATALOG(0),
    /**
     * 菜单
     */
    MENU(1),
    /**
     * 按钮
     */
    BUTTON(2);
    private int value;
    MenuType(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopEmployeeMapper.java
New file
@@ -0,0 +1,66 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.ShopEmployee;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
 * 商家端用户
 * @author person
 * @date 2021-03-01 17:42:09
 */
public interface ShopEmployeeMapper extends BaseMapper<ShopEmployee> {
    /**
     * 根据用户名或手机号获取用户信息以及店铺状态
     * @param username 用户名
     * @return 商家端用户信息
     */
    ShopEmployee getShopByUsernameOrMobile(@Param("username") String username);
    /**
     * 根据用户ID批量获取权限
     * @param employeeId 用户ID
     * @return 权限列表
     */
    List<String> queryAllPerms(@Param("employeeId") Long employeeId);
    /**
     * 根据用户名获取用户信息
     * @param username 用户名
     * @return 商家端用户信息
     */
    ShopEmployee getByUserName(@Param("username") String username);
    /**
     * 根据店铺id获取商家账号信息
     * @param shopId
     * @return
     */
    ShopEmployee getMerchantInfoByShopId(@Param("shopId") Long shopId);
    /**
     * 获取员工列表
     * @param shopEmployee
     * @return
     */
    List<ShopEmployee> listByParam(@Param("shopEmployee") ShopEmployee shopEmployee);
    @Select("select employee_id from tz_shop_employee where shop_id = #{id}")
    Long selectByUserId(Long id);
    @Select("select count(0) from tz_shop_employee where shop_id = #{shopId}")
    Integer selectEmployeeCount(Long shopId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopEmployeeRoleMapper.java
New file
@@ -0,0 +1,64 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.ShopEmployeeRole;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 用户与角色对应关系
 *
 * @author person
 * @date 2021-03-01 17:42:09
 */
public interface ShopEmployeeRoleMapper extends BaseMapper<ShopEmployeeRole> {
    /**
     * 根据角色ID数组,批量删除
     *
     * @param roleIds 角色ID
     * @return 成功数量
     */
    int deleteBatch(@Param("roleIds") List<Long> roleIds);
    /**
     * 批量插入用户与角色对应关系
     *
     * @param employeeId 用户ID
     * @param roleIdList 角色列表
     * @return 成功数量
     */
    int insertUserAndUserRole(@Param("employeeId") Long employeeId, @Param("roleIdList") List<Long> roleIdList);
    /**
     * 根据用户ID删除用户与角色对应关系
     *
     * @param employeeId 用户ID
     * @return 成功数量
     */
    int deleteByEmployeeId(@Param("employeeId") Long employeeId);
    /**
     * 根据用户ID列表批量删除
     *
     * @param employeeIds
     */
    void deleteByEmployeeIds(@Param("employeeIds") List<Long> employeeIds);
    /**
     * 获取使用过中的角色id列表
     *
     * @param roleIds
     */
    List<Long> selectUseRoleIds(@Param("roleIds") List<Long> roleIds);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopMenuMapper.java
New file
@@ -0,0 +1,114 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.ShopMenu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Set;
/**
 * 菜单管理
 *
 * @author yami
 * @date 2021-03-01 17:42:09
 */
public interface ShopMenuMapper extends BaseMapper<ShopMenu> {
    /**
     * 获取所有菜单信息与按钮列表
     *
     * @param lang 当前选择语言
     * @return 菜单信息与按钮列表
     */
    List<ShopMenu> listMenuAndBtn(@Param("lang") Integer lang);
    /**
     * 获取不是按钮类型的菜单列表
     *
     * @param lang 当前选择语言
     * @return 菜单列表
     */
    List<ShopMenu> listSimpleMenuNoButton(@Param("lang") Integer lang);
    /**
     * 获取类型为目录的菜单列表
     *
     * @param lang 当前选择语言
     * @return 菜单列表
     */
    List<ShopMenu> listRootMenu(@Param("lang") Integer lang);
    /**
     * 根据父ID获取所有子菜单列表
     *
     * @param parentId 商品ID
     * @param lang     当前选择语言
     * @return 菜单列表
     */
    List<ShopMenu> listChildrenMenuByParentId(@Param("parentId") Long parentId, @Param("lang") Integer lang);
    /**
     * 查询所有菜单
     *
     * @param lang 当前选择语言
     * @return 菜单列表
     */
    List<ShopMenu> listMenu(@Param("lang") Integer lang);
    /**
     * 查询用户的所有菜单
     *
     * @param employeeId 用户ID
     * @param lang       当前选择语言
     * @return 菜单列表
     */
    List<ShopMenu> listMenuByEmployeeId(@Param("employeeId") Long employeeId, @Param("lang") Integer lang);
    /**
     * 查询角色对应的菜单ID
     *
     * @param roleId
     * @return 菜单ID列表
     */
    List<Long> listMenuIdByRoleId(@Param("roleId") Long roleId);
    List<String> listMenuNameByPerms(@Param("perms") String perms, @Param("lang") Integer lang);
    /**
     * 根据父菜单id修改子菜单和子按钮的是否隐藏状态
     * @param parentId 父id
     * @param state 状态
     */
    int updateSonMenuState(@Param("parentId") Long parentId, @Param("state") Integer state);
    /**
     * 获取隐藏的按钮权限
     * @return
     */
    Set<String> listConcealButtonPerms();
    /**
     * 根据父菜单id获取所以子按钮的权限
     * @param parentId
     * @return
     */
    Set<String> listMenuPerms(@Param("parentId") Long parentId);
    /**
     * 根据店铺员工id获取员工所拥有的菜单权限列表
     * @param lang
     * @param employeeId
     * @return
     */
    List<ShopMenu> listRoleMenuAndBtn(@Param("lang") Integer lang,@Param("employeeId") Long employeeId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopRoleMapper.java
New file
@@ -0,0 +1,38 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.ShopRole;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 角色
 * @author yami
 * @date 2021-03-01 17:42:09
 */
public interface ShopRoleMapper extends BaseMapper<ShopRole> {
    /**
     * 根据ID列表批量删除角色
     * @param roleIds 角色ID列表
     */
    void deleteBatch(@Param("roleIds") List<Long> roleIds);
    /**
     * 根据用户ID获取用户对应的角色列表
     * @param employeeId 用户id
     * @return 角色ID列表
     */
    List<Long> listRoleIdByEmployeeId(@Param("employeeId") Long employeeId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/ShopRoleMenuMapper.java
New file
@@ -0,0 +1,48 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.ShopRoleMenu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 角色与菜单对应关系
 *
 * @author yami
 * @date 2021-03-01 17:42:09
 */
public interface ShopRoleMenuMapper extends BaseMapper<ShopRoleMenu> {
    /**
     * 根据菜单ID批量删除角色与菜单对应关系
     *
     * @param menuId 菜单ID
     */
    void deleteByMenuId(@Param("menuId") Long menuId);
    /**
     * 批量插入角色与菜单对应关系
     *
     * @param roleId     角色ID
     * @param menuIdList 角色与菜单对应关系列表
     */
    void insertRoleAndRoleMenu(@Param("roleId") Long roleId, @Param("menuIdList") List<Long> menuIdList);
    /**
     * 根据角色ID数组,批量删除
     *
     * @param roleIds 角色ID列表
     * @return 成功数量
     */
    int deleteBatch(@Param("roleIds") List<Long> roleIds);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysLogMapper.java
New file
@@ -0,0 +1,22 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.SysLog;
/**
 * 系统日志
 * @author yami
 */
public interface SysLogMapper extends BaseMapper<SysLog> {
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysMenuMapper.java
New file
@@ -0,0 +1,121 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.SysMenu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Set;
/**
 * 菜单管理
 *
 * @author lgh
 */
public interface SysMenuMapper extends BaseMapper<SysMenu> {
    /**
     * 根据角色id获取菜单列表
     *
     * @param roleId 角色id
     * @return 菜单id列表
     */
    List<Long> listMenuIdByRoleId(@Param("roleId") Long roleId);
    /**
     * 查询用户的所有菜单ID
     *
     * @param userId 用户id
     * @param lang   当前选择语言
     * @return 该用户所有可用的菜单
     */
    List<SysMenu> listMenuByUserId(@Param("userId") Long userId, @Param("lang") Integer lang);
    /**
     * 获取系统的所有菜单
     *
     * @param lang 当前选择语言
     * @return 系统的所有菜单
     */
    List<SysMenu> listMenu(@Param("lang") Integer lang);
    /**
     * 获取简单的menu tree 用于在 ele-ui tree中显示,根据orderNum排序
     *
     * @param lang 当前选择语言
     * @return ztreeDto列表
     */
    List<SysMenu> listSimpleMenuNoButton(@Param("lang") Integer lang);
    /**
     * 获取一级菜单
     *
     * @param lang 当前选择语言
     * @return 一级菜单列表
     */
    List<SysMenu> listRootMenu(@Param("lang") Integer lang);
    /**
     * 根据一级菜单id 获取二级菜单
     *
     * @param parentId 一级菜单id
     * @param lang     当前选择语言
     * @return 二级菜单列表
     */
    List<SysMenu> listChildrenMenuByParentId(@Param("parentId") Long parentId, @Param("lang") Integer lang);
    /**
     * 批量获取菜单以及按钮
     *
     * @param lang 当前选择语言
     * @return 系统的所有菜单以及按钮
     */
    List<SysMenu> listMenuAndBtn(@Param("lang") Integer lang);
    /**
     *
     * @param perms
     * @param lang
     * @return
     */
    List<String> listMenuNameByPerms(@Param("perms") String perms, @Param("lang") Integer lang);
    /**
     * 根据父菜单id修改子菜单和子按钮的是否隐藏状态
     * @param parentId 父id
     * @param state 状态
     */
    int updateSonMenuState(@Param("parentId") Long parentId, @Param("state") Integer state);
    /**
     * 根据父菜单id获取所以子按钮的权限
     * @param parentId
     * @return
     */
    Set<String> listMenuPerms(@Param("parentId") Long parentId);
    /**
     * 获取隐藏的按钮权限
     * @return
     */
    Set<String> listConcealButtonPerms();
    /**
     * 根据角色id批量获取角色拥有菜单以及按钮
     *
     * @param lang 当前选择语言
     * @return 系统的所有菜单以及按钮
     */
    List<SysMenu> listRoleMenuAndBtn(@Param("lang") Integer lang, @Param("userId") Long userId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysRoleMapper.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.SysRole;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 角色管理
 * @author yami
 */
public interface SysRoleMapper extends BaseMapper<SysRole>{
    /**
     * 根据系统角色ID列表批量删除角色
     * @param roleIds 系统角色ID列表
     */
    void deleteBatch(@Param("roleIds") List<Long> roleIds);
    /**
     * 根据用户ID获取对应的角色ID列表
     * @param userId 用户ID
     * @return 系统角色ID列表
     */
    List<Long> listRoleIdByUserId(Long userId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysRoleMenuMapper.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.SysRoleMenu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 角色与菜单对应关系
 *
 * @author yami
 */
public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenu> {
    /**
     * 根据角色ID数组,批量删除
     *
     * @param roleIds
     * @return 成功数量
     */
    int deleteBatch(@Param("roleIds") List<Long> roleIds);
    /**
     * 根据菜单id 删除菜单关联角色信息
     *
     * @param menuId 菜单ID
     */
    void deleteByMenuId(@Param("menuId") Long menuId);
    /**
     * 根据角色id 批量添加角色与菜单关系
     *
     * @param roleId     角色ID
     * @param menuIdList 角色与菜单关系列表
     */
    void insertRoleAndRoleMenu(@Param("roleId") Long roleId, @Param("menuIdList") List<Long> menuIdList);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysUserMapper.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.SysUser;
import java.util.List;
/**
 * 系统用户
 * @author yami
 */
public interface SysUserMapper extends BaseMapper<SysUser> {
    /**
     * 查询用户的所有权限
     * @param userId 用户ID
     * @return 权限列表
     */
    List<String> queryAllPerms(Long userId);
    /**
     * 根据用户名获取管理员用户
     * @param username 用户名
     * @return 系统用户
     */
    SysUser selectByUsername(String username);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/dao/SysUserRoleMapper.java
New file
@@ -0,0 +1,54 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.sys.common.model.SysUserRole;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 用户与角色对应关系
 *
 * @author yami
 */
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
    /**
     * 根据角色ID数组,批量删除
     *
     * @param roleIds 角色ID列表
     * @return 成功数量
     */
    int deleteBatch(@Param("roleIds") List<Long> roleIds);
    /**
     * 根据用户id删除用户与角色关系
     *
     * @param userId 用户ID
     */
    void deleteByUserId(Long userId);
    /**
     * 根据用户id 批量添加用户角色关系
     *
     * @param userId     用户ID
     * @param roleIdList 角色ID列表
     */
    void insertUserAndUserRole(@Param("userId") Long userId, @Param("roleIdList") List<Long> roleIdList);
    /**
     * 获取使用过中的角色id列表
     *
     * @param roleIds
     */
    List<Long> selectUseRoleIds(@Param("roleIds") List<Long> roleIds);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/listener/PermissionErrorHandleListener.java
New file
@@ -0,0 +1,60 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.listener;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.yami.shop.bean.event.PermissionErrorHandleEvent;
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.sys.common.dao.ShopMenuMapper;
import com.yami.shop.sys.common.dao.SysMenuMapper;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
/**
 * 用户没有权限的错误处理
 *
 * @author lhd
 */
@Component("permissionErrorHandleListener")
@AllArgsConstructor
public class PermissionErrorHandleListener {
    private final SysMenuMapper sysMenuMapper;
    private final ShopMenuMapper shopMenuMapper;
    @EventListener(PermissionErrorHandleEvent.class)
    public void permissionErrorHandleListener(PermissionErrorHandleEvent event) {
        if (StrUtil.isBlank(event.getPerms())) {
            return;
        }
        Integer lang = I18nMessage.getLang();
        List<String> list;
        // 平台端
        if (Objects.equals(event.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            list = sysMenuMapper.listMenuNameByPerms(event.getPerms(), lang);
        }
        // 商家端
        else {
            list = shopMenuMapper.listMenuNameByPerms(event.getPerms(), lang);
        }
        if (CollUtil.isEmpty(list)) {
            return;
        }
        String messagePre = I18nMessage.getMessage("yami.lack.permission.pre");
        String messageSuf = I18nMessage.getMessage("yami.lack.permission.suf");
        throw new YamiShopBindException(messagePre + list.toString() + messageSuf);
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/listener/ShopEmployeeSuperAdminListener.java
New file
@@ -0,0 +1,109 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.listener;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.dto.ShopUserRegisterDto;
import com.yami.shop.bean.enums.PositionType;
import com.yami.shop.bean.enums.SendType;
import com.yami.shop.bean.event.ShopEmployeeSuperAdminEvent;
import com.yami.shop.bean.event.UpdateShopAccountEvent;
import com.yami.shop.bean.event.UpdateShopSuperAdminAccountEvent;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.common.manager.PasswordManager;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.service.SmsLogService;
import com.yami.shop.sys.common.model.ShopEmployee;
import com.yami.shop.sys.common.service.ShopEmployeeService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.context.event.EventListener;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;
/**
 * 新增店铺职工
 * @author LGH
 */
@Component("shopEmployeeSuperAdmin")
@AllArgsConstructor
public class ShopEmployeeSuperAdminListener {
    private final ShopEmployeeService shopEmployeeService;
    private final MapperFacade mapperFacade;
    private final PasswordEncoder passwordEncoder;
    private final ShopDetailService shopDetailService;
    private final SmsLogService smsLogService;
    private final PasswordManager passwordManager;
    @EventListener(ShopEmployeeSuperAdminEvent.class)
    public void shopEmployeeSuperAdminListener(ShopEmployeeSuperAdminEvent event) {
        ShopUserRegisterDto shopUserRegisterDto = event.getShopUserRegisterDto();
        if (Objects.isNull(shopUserRegisterDto)) {
            return;
        }
        int countByUsername = shopEmployeeService.count(Wrappers.lambdaQuery(ShopEmployee.class)
                .eq(ShopEmployee::getUsername, shopUserRegisterDto.getUsername())
                .ne(ShopEmployee::getShopId, shopUserRegisterDto.getShopId()));
        if (countByUsername > 0) {
            throw new YamiShopBindException("yami.user.account.exist");
        }
        int countByMobile = shopEmployeeService.count(Wrappers.lambdaQuery(ShopEmployee.class)
                .eq(ShopEmployee::getMobile, shopUserRegisterDto.getMobile())
                .ne(ShopEmployee::getShopId, shopUserRegisterDto.getMobile()));
        if (countByMobile > 0) {
            throw new YamiShopBindException("yami.phone.number.already.exists");
        }
        if (Objects.nonNull(shopUserRegisterDto.getValidCode())) {
            if (!smsLogService.checkValidCode(shopUserRegisterDto.getMobile(), shopUserRegisterDto.getValidCode(), SendType.VALID)){
                // 验证码有误或已过期
                throw new YamiShopBindException("yami.user.code.error");
            }
        }
        String decryptPassword = passwordManager.decryptPassword(shopUserRegisterDto.getPassword());
        Date now = new Date();
        ShopEmployee shopEmployee = new ShopEmployee();
        shopEmployee.setShopId(shopUserRegisterDto.getShopId());
        shopEmployee.setType(PositionType.ADMIN.value());
        shopEmployee.setUsername(shopUserRegisterDto.getUsername());
        shopEmployee.setNickname(shopUserRegisterDto.getUsername());
        shopEmployee.setMobile(shopUserRegisterDto.getMobile());
        shopEmployee.setStatus(1);
        shopEmployee.setCreateEmployeeId(0L);
        String password = passwordEncoder.encode(decryptPassword);
        shopEmployee.setPassword(password);
        shopEmployee.setCreateTime(now);
        shopEmployeeService.save(shopEmployee);
        // 店铺更新店长id
        shopDetailService.update(Wrappers.lambdaUpdate(ShopDetail.class).set(ShopDetail::getUserId, shopEmployee.getEmployeeId()).eq(ShopDetail::getShopId, shopUserRegisterDto.getShopId()));
    }
    @EventListener(UpdateShopSuperAdminAccountEvent.class)
    public void updateShopEmployeeSuperAdminListener(UpdateShopSuperAdminAccountEvent event) {
        ShopDetail shopDetail = event.getShopDetail();
        ShopEmployee shopEmployee = new ShopEmployee();
        mapperFacade.map(shopDetail,shopEmployee);
        shopEmployee.setMobile(shopDetail.getMobile());
        shopEmployeeService.updatePasswordAndUserName(shopEmployee);
    }
    @EventListener(UpdateShopAccountEvent.class)
    public void updateShopEmployeeSuperAdminListener(UpdateShopAccountEvent event) {
        ShopDetail shopDetail = event.getShopDetail();
        ShopEmployee shopEmployee = new ShopEmployee();
        shopEmployee.setShopId(shopDetail.getShopId());
        shopEmployee.setMobile(shopDetail.getMobile());
        shopEmployeeService.updatePasswordAndUserName(shopEmployee);
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopEmployee.java
New file
@@ -0,0 +1,93 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * 商家端用户
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Data
@TableName("tz_shop_employee")
public class ShopEmployee implements Serializable{
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "店铺职员id" )
    private Long employeeId;
    @Schema(description = "店铺id" )
    private Long shopId;
    @Schema(description = "用户id" )
    private String userId;
    @Schema(description = "职位:0 店铺超级管理员 1员工" )
    private Integer type;
    @Schema(description = "手机号(唯一),可作为登陆账号" )
    private String mobile;
    @NotBlank(message="用户名不能为空")
    @Size(min = 2,max = 20,message = "用户名长度要在2-20之间")
    @Schema(description = "用户名(唯一),可作为登陆账号" )
    private String username;
    @Schema(description = "昵称" )
    private String nickname;
    @Schema(description = "密码" )
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;
    @NotBlank(message="邮箱不能为空")
    @Email(message="邮箱格式不正确")
    @Schema(description = "邮箱" )
    private String email;
    @Schema(description = "状态  0:禁用   1:正常" )
    private Integer status;
    @Schema(description = "创建者ID" )
    private Long createEmployeeId;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "创建时间" )
    private Date createTime;
    @TableField(exist = false)
    @Schema(description = "店铺状态(-1:已删除 0:停业中 1:营业中 2:违规下线 3:违规审核 4:开店申请中 5:开店申请待审核" )
    private Integer shopStatus;
    @TableField(exist=false)
    @Schema(description = "角色ID列表" )
    private List<Long> roleIdList;
    @TableField(exist = false)
    @Schema(description = "店铺名称" )
    private String shopName;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopEmployeeRole.java
New file
@@ -0,0 +1,42 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 * 商家端用户与角色对应关系
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Data
@TableName("tz_shop_employee_role")
public class ShopEmployeeRole implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId
    private Long id;
    /**
     * 用户ID
     */
    private Long employeeId;
    /**
     * 角色ID
     */
    private Long roleId;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopMenu.java
New file
@@ -0,0 +1,100 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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 javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
 * 店铺菜单管理
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Data
@TableName("tz_shop_menu")
public class ShopMenu implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId
    @Schema(description = "菜单id" )
    private Long menuId;
    /**
     * 父菜单ID,一级菜单为0
     */
    @NotNull(message="上级菜单不能为空")
    @Schema(description = "父菜单ID,一级菜单为0" )
    private Long parentId;
    /**
     * 菜单名称
     *
     */
    @Schema(description = "菜单名称" )
    @NotBlank(message="菜单名称不能为空")
    private String name;
    /**
     * 菜单URL
     */
    @Schema(description = "菜单URL" )
    private String url;
    /**
     * 授权(多个用逗号分隔,如:user:list,user:create)
     */
    @Schema(description = "授权(多个用逗号分隔,如:user:list,user:create)" )
    private String perms;
    /**
     * 类型   0:目录   1:菜单   2:按钮
     */
    @Schema(description = "类型   0:目录   1:菜单   2:按钮" )
    private Integer type;
    /**
     * 菜单图标
     */
    @Schema(description = "菜单图标" )
    private String icon;
    /**
     * 排序
     */
    @Schema(description = "排序" )
    private Integer orderNum;
    /**
     * 菜单英文名称
     */
    @Schema(description = "菜单英文名称" )
    private String nameEn;
    /**
     * 是否隐藏 当设置 true 的时候该路由不会在侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
     */
    @Schema(description = "是否隐藏 当设置 true 的时候该路由不会在侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1" )
    @NotNull(message="是否隐藏属性不能为空")
    private Integer hidden;
    /**
     * 父菜单名称
     */
    @Schema(description = "父菜单名称" )
    @TableField(exist=false)
    private String parentName;
    @TableField(exist=false)
    private List<?> list;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopRole.java
New file
@@ -0,0 +1,70 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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 org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * 店铺角色
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Data
@TableName("tz_shop_role")
public class ShopRole implements Serializable{
    private static final long serialVersionUID = 1L;
    @TableId
    @Schema(description = "角色id" )
    private Long roleId;
    /**
     * 店铺id
     */
    @Schema(description = "店铺id" )
    private Long shopId;
    /**
     * 角色名称
     */
    @Schema(description = "角色名称" )
    @NotBlank(message="角色名称不能为空")
    private String roleName;
    /**
     * 备注
     */
    @Schema(description = "备注" )
    private String remark;
    /**
     * 创建者ID
     */
    @Schema(description = "创建者ID" )
    private Long createEmployeeId;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @TableField(exist=false)
    @Schema(description = "菜单id列表" )
    private List<Long> menuIdList;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/ShopRoleMenu.java
New file
@@ -0,0 +1,42 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 * 店铺角色与菜单对应关系
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Data
@TableName("tz_shop_role_menu")
public class ShopRoleMenu implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId
    private Long id;
    /**
     * 角色ID
     */
    private Long roleId;
    /**
     * 菜单ID
     */
    private Long menuId;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysLog.java
New file
@@ -0,0 +1,55 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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 yami
 */
@Data
@TableName("tz_sys_log")
public class SysLog implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    private Long id;
    @Schema(description = "用户名" )
    private String username;
    @Schema(description = "用户操作" )
    private String operation;
    @Schema(description = "请求方法" )
    private String method;
    @Schema(description = "请求参数" )
    private String params;
    @Schema(description = "执行时长(毫秒)" )
    private Long time;
    @Schema(description = "IP地址" )
    private String ip;
    @Schema(description = "创建时间" )
    private Date createDate;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysMenu.java
New file
@@ -0,0 +1,81 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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 javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
 * 菜单管理
 *
 * @author yami
 */
@Data
@TableName("tz_sys_menu")
public class SysMenu implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 菜单ID
     */
    @TableId
    @Schema(description = "菜单id" )
    private Long menuId;
    @NotNull(message="上级菜单不能为空")
    @Schema(description = "父菜单ID,一级菜单为0" )
    private Long parentId;
    @TableField(exist=false)
    @Schema(description = "父菜单名称" )
    private String parentName;
    @NotBlank(message="菜单名称不能为空")
    @Schema(description = "菜单名称" )
    private String name;
    @Schema(description = "菜单英文名称" )
    private String nameEn;
    @Schema(description = "菜单URL" )
    private String url;
    @Schema(description = "授权(多个用逗号分隔,如:user:list,user:create)" )
    private String perms;
    @Schema(description = "类型  0:目录 1:菜单 2:按钮" )
    private Integer type;
    @Schema(description = "菜单图标" )
    private String icon;
    @Schema(description = "排序" )
    private Integer orderNum;
    /**
     * 是否隐藏 当设置 true 的时候该路由不会在侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
     */
    @NotNull(message="是否隐藏属性不能为空")
    @Schema(description = "是否隐藏" )
    private Integer hidden;
    @TableField(exist=false)
    private List<?> list;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysRole.java
New file
@@ -0,0 +1,56 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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 org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * 角色
 * @author yami
 */
@Data
@TableName("tz_sys_role")
public class SysRole implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     *
     */
    @TableId
    @Schema(description = "角色ID" )
    private Long roleId;
    @NotBlank(message="角色名称不能为空")
    @Schema(description = "角色名称" )
    private String roleName;
    @Schema(description = "备注" )
    private String remark;
    @TableField(exist=false)
    @Schema(description = "菜单id列表" )
    private List<Long> menuIdList;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Schema(description = "创建时间" )
    private Date createTime;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysRoleMenu.java
New file
@@ -0,0 +1,41 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 * 角色与菜单对应关系
 *
 * @author yami
 */
@Data
@TableName("tz_sys_role_menu")
public class SysRoleMenu implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    private Long id;
    /**
     * 角色ID
     */
    private Long roleId;
    /**
     * 菜单ID
     */
    private Long menuId;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysUser.java
New file
@@ -0,0 +1,85 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.yami.shop.common.util.PrincipalUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * 系统用户
 * @author yami
 */
@Data
@TableName("tz_sys_user")
public class SysUser implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     *
     */
    @TableId
    @Schema(description = "用户ID" )
    private Long userId;
    @Schema(description = "用户名" )
    @NotBlank(message="用户名不能为空")
    @Size(min = 2,max = 20,message = "用户名长度要在2-20之间")
    private String username;
    @Schema(description = "用户昵称" )
    @NotBlank(message="用户昵称")
    @Size(min = 2,max = 20,message = "用户昵称长度要在2-20之间")
    private String nickName;
    @Schema(description = "密码" )
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;
    @Schema(description = "邮箱" )
    @NotBlank(message="邮箱不能为空")
    @Email(message="邮箱格式不正确")
    private String email;
    @Schema(description = "手机号" )
    @Pattern(regexp= PrincipalUtil.MOBILE_REGEXP,message = "请输入正确的手机号")
    private String mobile;
    @Schema(description = "状态 0:禁用 1:正常" )
    private Integer status;
    @Schema(description = "角色ID列表" )
    @TableField(exist=false)
    private List<Long> roleIdList;
    @Schema(description = "创建时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @Schema(description = "是否本人" )
    @TableField(exist = false)
    private Integer isSelf;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/model/SysUserRole.java
New file
@@ -0,0 +1,39 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 * 用户与角色对应关系
 * @author yami
 */
@Data
@TableName("tz_sys_user_role")
public class SysUserRole implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId
    private Long id;
    /**
     * 用户ID
     */
    private Long userId;
    /**
     * 角色ID
     */
    private Long roleId;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopEmployeeRoleService.java
New file
@@ -0,0 +1,22 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.ShopEmployeeRole;
/**
 * 用户与角色对应关系
 * @author yami
 * @date 2021-03-01 17:42:09
 */
public interface ShopEmployeeRoleService extends IService<ShopEmployeeRole> {
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopEmployeeService.java
New file
@@ -0,0 +1,137 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.dto.ShopUserRegisterDto;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.sys.common.model.ShopEmployee;
import java.util.List;
/**
 * 商家端用户
 * @author person
 * @date 2021-03-01 17:42:09
 */
public interface ShopEmployeeService extends IService<ShopEmployee> {
    /**
     * 根据用户ID获取用户信息
     * @param employeeId 用户ID
     * @return 用户信息
     */
    ShopEmployee getShopEmployeeById(Long employeeId);
    /**
     * 根据用户ID更新密码
     * @param employeeId 用户ID
     * @param newPassword 新密码
     * @return 是否成功
     */
    Boolean updatePasswordByEmployeeId(Long employeeId, String newPassword);
    /**
     * 保存用户信息以及保存用户与角色关系
     * @param shopEmployee 用户信息
     * @return 是否成功
     */
    Boolean saveUserAndUserRole(ShopEmployee shopEmployee);
    /**
     * 根据用户名获取用户信息
     * @param username 用户名
     * @return 用户信息
     */
    ShopEmployee getByUserName(String username);
    /**
     * 更新用户以及用户与角色关系
     * @param shopEmployee 用户信息
     * @return 是否成功
     */
    Boolean updateUserAndUserRole(ShopEmployee shopEmployee);
    /**
     * 根据店铺ID检查用户名已存在的数量
     * @param shopId 店铺ID
     * @param mobile 手机号
     * @return 返回数量
     */
    int checkUserName(Long shopId, String mobile);
    /**
     * 更新用户信息
     * @param shopEmployee 用户信息
     * @return 是否成功
     */
    Boolean updatePasswordAndUserName(ShopEmployee shopEmployee);
    /**
     * 更新密码
     * @param employeeId 用户ID
     * @param newPassword 新密码
     * @return 是否成功
     */
    Boolean updatePassword(Long employeeId, String newPassword);
    /**
     * 更新店铺信息以及店铺超级管理员信息
     * @param shopDetail 店铺详细信息
     * @return 是否成功
     */
    Boolean updateUserNameAndPassword(ShopDetail shopDetail);
    /**
     * 根据手机号更新密码
     * @param mobile 手机号
     * @param newPassword 新密码
     * @return 是否成功
     */
    Boolean updatePasswordByUserName(String mobile, String newPassword);
    /**
     * 注册商家账号
     *
     * @param shopUserRegisterDTO
     * @return
     */
    ShopEmployee registerMerchant(ShopUserRegisterDto shopUserRegisterDTO);
    /**
     * 根据员工id列表删除员工信息
     * @param employeeIds
     */
    void removeEmployeesByIds(List<Long> employeeIds);
    /**
     * 根据店铺id获取店铺商家账号信息
     * @param shopId
     * @return
     */
    ShopEmployee getMerchantInfoByShopId(Long shopId);
    /**
     * 更新商家信息
     * @param shopEmployee
     */
    void updateMerchantInfo(ShopEmployee shopEmployee);
    /**
     * 获取员工列表
     * @param shopEmployee
     * @return
     */
    List<ShopEmployee> listByParam(ShopEmployee shopEmployee);
    Long getShopEmployeeByUserId(Long id);
    Integer getShopEmployeeCountByShopId(Long shopId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopMenuService.java
New file
@@ -0,0 +1,93 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.ShopEmployee;
import com.yami.shop.sys.common.model.ShopMenu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Set;
/**
 * 菜单管理
 * @author yami
 * @date 2021-03-01 17:42:09
 */
public interface ShopMenuService extends IService<ShopMenu> {
    /**
     * 获取所有菜单信息与按钮列表
     * @param employeeId 用户id
     * @return 菜单信息与按钮列表
     */
    List<ShopMenu> listMenuAndBtn(Long employeeId);
    /**
     * 获取不是按钮类型的菜单列表
     * @return 菜单列表
     */
    List<ShopMenu> listSimpleMenuNoButton();
    /**
     * 获取类型为目录的菜单列表
     * @return 菜单列表
     */
    List<ShopMenu> listRootMenu();
    /**
     * 根据父ID获取所有子菜单列表
     * @param parentId 父ID
     * @return 菜单列表
     */
    List<ShopMenu> listChildrenMenuByParentId(Long parentId);
    /**
     * 根据菜单ID删除菜单以及删除菜单与角色关联关系
     * @param menuId 菜单ID
     */
    void deleteMenuAndRoleMenu(Long menuId);
    /**
     * 根据用户ID获取菜单列表
     * @param employeeId 用户ID
     * @return 菜单列表
     */
    List<ShopMenu> listMenuByEmployeeId(Long employeeId);
    /**
     * 查询角色对应的菜单ID
     * @param roleId 角色ID
     * @return 菜单ID列表
     */
    List<Long> listMenuIdByRoleId(Long roleId);
    /**
     * 根据父菜单id修改子菜单和子按钮的是否隐藏状态,返回子按钮的权限信息
     * @param parentId 父id
     * @param state 状态
     * @return 子按钮权限信息
     */
    Set<String> updateSonMenuState(@Param("parentId") Long parentId, @Param("state") Integer state);
    /**
     * 获取隐藏的按钮权限
     * @return
     */
    Set<String> listConcealButtonPerms();
    /**
     * 获取当前商家拥有的权限
     * @param shopEmployee
     * @return
     */
    Set<String> getShopPermissions(ShopEmployee shopEmployee);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopRoleMenuService.java
New file
@@ -0,0 +1,22 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.ShopRoleMenu;
/**
 * 角色与菜单对应关系
 * @author yami
 * @date 2021-03-01 17:42:09
 */
public interface ShopRoleMenuService extends IService<ShopRoleMenu> {
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/ShopRoleService.java
New file
@@ -0,0 +1,51 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.ShopRole;
import java.util.List;
/**
 * 角色
 * @author yami
 * @date 2021-03-01 17:42:09
 */
public interface ShopRoleService extends IService<ShopRole> {
    /**
     * 保存角色以及保存角色与菜单关系
     * @param shopRole 店铺角色
     * @return 是否成功
     */
    Boolean saveRoleAndRoleMenu(ShopRole shopRole);
    /**
     * 更新角色以及更新角色与菜单关系
     * @param shopRole 店铺角色
     * @return 是否成功
     */
    Boolean updateRoleAndRoleMenu(ShopRole shopRole);
    /**
     * 根据角色ID列表批量删除角色以及角色与菜单关系
     * @param roleIds 角色ID列表
     * @return 是否成功
     */
    Boolean deleteBatch(Long[] roleIds);
    /**
     * 根据用户ID获取用户对应的角色列表
     * @param employeeId 用户ID
     * @return 角色ID列表
     */
    List<Long> listRoleIdByEmployeeId(Long employeeId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysLogService.java
New file
@@ -0,0 +1,23 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.SysLog;
/**
 * 系统日志
 * @author lgh
 */
public interface SysLogService extends IService<SysLog> {
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysMenuService.java
New file
@@ -0,0 +1,83 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.SysMenu;
import java.util.List;
import java.util.Set;
/**
 * 菜单管理
 * @author lgh
 */
public interface SysMenuService extends IService<SysMenu> {
    /**
     * 获取用户菜单列表
     * @param userId 用户id
     * @return 菜单列表
     */
    List<SysMenu> listMenuByUserId(Long userId);
    /**
     * 删除 菜单,与角色菜单之间的关系
     * @param menuId 菜单id
     */
    void deleteMenuAndRoleMenu(Long menuId);
    /**
     * 根据角色ID,获取菜单列表
     * @param roleId 角色id
     * @return 角色所拥有的菜单id列表
     */
    List<Long> listMenuIdByRoleId(Long roleId);
    /**
     * 获取简单的menu tree 用于在ele-ui tree中显示,根据orderNum排序
     * @return 所有的菜单
     */
    List<SysMenu> listSimpleMenuNoButton();
    /**
     * 获取一级菜单
     * @return 一级菜单列表
     */
    List<SysMenu> listRootMenu();
    /**
     * 根据一级菜单id 获取二级菜单
     * @param parentId 一级菜单id
     * @return 二级菜单列表
     */
    List<SysMenu> listChildrenMenuByParentId(Long parentId);
    /**
     * 批量获取菜单以及按钮
     * @return 系统的所有菜单以及按钮
     */
    List<SysMenu> listMenuAndBtn(Long userId);
    /**
     * 根据菜单id修改子菜单和子按钮的是否隐藏状态
     * @param menuId 菜单id
     * @param state 状态
     */
    Set<String> updateSonMenuState(Long menuId, Integer state);
    /**
     * 获取被隐藏的按钮权限
     * @return
     */
    Set<String> listConcealButtonPerms();
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysRoleService.java
New file
@@ -0,0 +1,49 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.SysRole;
import java.util.List;
/**
 * 角色
 * @author lgh
 */
public interface SysRoleService extends IService<SysRole> {
    /**
     * 根据id批量删除
     * @param roleIds 角色ID列表
     */
    void deleteBatch(List<Long> roleIds);
    /**
     * 保存角色 与 角色菜单关系
     * @param role 角色信息
     */
    void saveRoleAndRoleMenu(SysRole role);
    /**
     * 更新角色 与 角色菜单关系
     * @param role 角色信息
     */
    void updateRoleAndRoleMenu(SysRole role);
    /**
     * 根据用户ID,获取角色ID列表
     * @param userId 用户id
     * @return 角色id列表
     */
    List<Long> listRoleIdByUserId(Long userId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/SysUserService.java
New file
@@ -0,0 +1,56 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.sys.common.model.SysUser;
/**
 * 系统用户
 * @author lgh
 */
public interface SysUserService extends IService<SysUser> {
    /**
     * 修改密码
     * @param userId       用户ID
     * @param newPassword  新密码
     */
    void updatePasswordByUserId(Long userId, String newPassword);
    /**
     * 保存用户与用户角色关系
     * @param user 系统用户信息
     */
    void saveUserAndUserRole(SysUser user);
    /**
     * 更新用户与用户角色关系
     * @param user 系统用户信息
     */
    void updateUserAndUserRole(SysUser user);
    /**
     * 根据用户名获取用户信息
     * @param username 用户名
     * @return 系统用户
     */
    SysUser getByUserName(String username);
    /**
     * 根据用户id获取用户信息
     * @param userId 用户ID
     * @return 系统用户
     */
    SysUser getSysUserById(Long userId);
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopEmployeeRoleServiceImpl.java
New file
@@ -0,0 +1,29 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.sys.common.dao.ShopEmployeeRoleMapper;
import com.yami.shop.sys.common.model.ShopEmployeeRole;
import com.yami.shop.sys.common.service.ShopEmployeeRoleService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
/**
 * 用户与角色对应关系
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Service
@AllArgsConstructor
public class ShopEmployeeRoleServiceImpl extends ServiceImpl<ShopEmployeeRoleMapper, ShopEmployeeRole> implements ShopEmployeeRoleService {
    private final ShopEmployeeRoleMapper shopEmployeeRoleMapper;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopEmployeeServiceImpl.java
New file
@@ -0,0 +1,291 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.dto.ShopUserRegisterDto;
import com.yami.shop.bean.enums.PositionType;
import com.yami.shop.bean.enums.SendType;
import com.yami.shop.bean.enums.ShopStatus;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.bean.model.TakeStock;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.common.manager.PasswordManager;
import com.yami.shop.service.ShopDetailService;
import com.yami.shop.service.SmsLogService;
import com.yami.shop.service.TakeStockService;
import com.yami.shop.sys.common.dao.ShopEmployeeMapper;
import com.yami.shop.sys.common.dao.ShopEmployeeRoleMapper;
import com.yami.shop.sys.common.model.ShopEmployee;
import com.yami.shop.sys.common.service.ShopEmployeeService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.security.crypto.password.PasswordEncoder;
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
 * @date 2021-03-01 17:42:09
 */
@Service
@AllArgsConstructor
public class ShopEmployeeServiceImpl extends ServiceImpl<ShopEmployeeMapper, ShopEmployee> implements ShopEmployeeService {
    private final ShopEmployeeMapper shopEmployeeMapper;
    private final ShopEmployeeRoleMapper shopEmployeeRoleMapper;
    private final ShopDetailService shopDetailService;
    private final PasswordEncoder passwordEncoder;
    private final SmsLogService smsLogService;
    private final MapperFacade mapperFacade;
    private final TakeStockService takeStockService;
    private final PasswordManager passwordManager;
    @Override
    public ShopEmployee getShopEmployeeById(Long employeeId) {
        return shopEmployeeMapper.selectById(employeeId);
    }
    @Override
    public Boolean updatePasswordByEmployeeId(Long employeeId, String newPassword) {
        ShopEmployee employee = new ShopEmployee();
        employee.setPassword(newPassword);
        employee.setEmployeeId(employeeId);
        Integer num = shopEmployeeMapper.updateById(employee);
        return num > 0;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveUserAndUserRole(ShopEmployee shopEmployee) {
        // 检查用户信息
        this.checkRegisterInfo(shopEmployee);
        shopEmployee.setCreateTime(new Date());
        shopEmployeeMapper.insert(shopEmployee);
        if(CollUtil.isEmpty(shopEmployee.getRoleIdList())){
            return true;
        }
        //保存用户与角色关系
        shopEmployeeRoleMapper.insertUserAndUserRole(shopEmployee.getEmployeeId(), shopEmployee.getRoleIdList());
        return true;
    }
    @Override
    public ShopEmployee getByUserName(String username) {
        return shopEmployeeMapper.getByUserName(username);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUserAndUserRole(ShopEmployee shopEmployee) {
        // 检查用户信息
        this.checkRegisterInfo(shopEmployee);
        // 更新用户
        shopEmployeeMapper.updateById(shopEmployee);
        //先删除用户与角色关系
        shopEmployeeRoleMapper.deleteByEmployeeId(shopEmployee.getEmployeeId());
        if(CollUtil.isEmpty(shopEmployee.getRoleIdList())){
            return true;
        }
        //保存用户与角色关系
        shopEmployeeRoleMapper.insertUserAndUserRole(shopEmployee.getEmployeeId(), shopEmployee.getRoleIdList());
        //更新盘点制单人手机号
        TakeStock stock = takeStockService.getOne(new LambdaQueryWrapper<TakeStock>().eq(TakeStock::getMaker, shopEmployee.getEmployeeId()));
        if (Objects.nonNull(stock)){
            stock.setMakerMobile(shopEmployee.getMobile());
            takeStockService.updateById(stock);
        }
        return true;
    }
    @Override
    public int checkUserName(Long shopId, String mobile) {
        // shopId 为空,判断username是否重复
        if (Objects.isNull(shopId) || Objects.equals(0L,shopId)) {
            return this.count(new LambdaQueryWrapper<ShopEmployee>()
                    .eq(ShopEmployee::getUsername, mobile));
        }
        // 更改超级商家店铺超级管理员时,判断username是否重复
        ShopEmployee employee = getEmployeeSuperAdminByShopId(shopId);
        int count = this.count(new LambdaQueryWrapper<ShopEmployee>()
                .eq(ShopEmployee::getUsername, mobile)
                .ne(ShopEmployee::getEmployeeId,employee.getEmployeeId()));
        return count;
    }
    private ShopEmployee getEmployeeSuperAdminByShopId(Long shopId) {
        // 查询到店铺超级管理员
        List<ShopEmployee> employee = shopEmployeeMapper.selectList(new LambdaQueryWrapper<ShopEmployee>()
                .eq(ShopEmployee::getType,  PositionType.ADMIN.value())
                .eq(ShopEmployee::getShopId, shopId));
        if (!Objects.equals(1, employee.size())) {
            // 一个店铺只允许有一个超级管理员,请检查 tz_shop_employee 和 tz_shop_detail 表中数据,
            // 清除掉多余的超级关理员。一个店铺需要仅一个超级管理员,请处理店铺账号数据
            throw new YamiShopBindException("yami.shop.account.have.only.one");
        }
       return employee.get(0);
    }
    @Override
    public Boolean updatePasswordAndUserName(ShopEmployee shopEmployee) {
        Long shopId = shopEmployee.getShopId();
        // 更改超级商家店铺超级管理员时,判断username是否重复
        // 查询到店铺超级管理员
        ShopEmployee employee = getEmployeeSuperAdminByShopId(shopId);
        Long employeeId = employee.getEmployeeId();
        int count = this.count(new LambdaQueryWrapper<ShopEmployee>()
                .eq(ShopEmployee::getUsername, shopEmployee.getUsername())
                .ne(ShopEmployee::getEmployeeId,employeeId));
        if (count > 0) {
            // 该账号已存在,请重新输入
            throw new YamiShopBindException("yami.store.account.exist");
        }
        shopEmployee.setEmployeeId(employeeId);
        return this.updateById(shopEmployee);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePassword(Long employeeId, String newPassword) {
        //        更新密码
        updatePasswordByEmployeeId(employeeId,newPassword);
        return true;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateUserNameAndPassword(ShopDetail shopDetail) {
        shopDetailService.updateById(shopDetail);
        String mobile = shopDetail.getMobile();
        String password = shopDetail.getPassword();
        Long shopId = shopDetail.getShopId();
        ShopEmployee employee = getEmployeeSuperAdminByShopId(shopId);
        ShopEmployee update = new ShopEmployee();
        update.setEmployeeId(employee.getEmployeeId());
        update.setUsername(mobile);
        update.setMobile(mobile);
        update.setPassword(password);
        return this.updateById(update);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePasswordByUserName(String mobile, String newPassword) {
        ShopEmployee employee = this.getByUserName(mobile);
        return this.updatePasswordByEmployeeId(employee.getEmployeeId(),newPassword);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ShopEmployee registerMerchant(ShopUserRegisterDto shopUserRegisterDTO) {
        ShopEmployee shopEmployee = mapperFacade.map(shopUserRegisterDTO, ShopEmployee.class);
        // 先校验注册信息
        this.checkRegisterInfo(shopEmployee);
        // 校验验证码
        if (!smsLogService.checkValidCode(shopUserRegisterDTO.getMobile(), shopUserRegisterDTO.getValidCode(), SendType.VALID)){
            // 验证码有误或已过期
            throw new YamiShopBindException("yami.user.code.error");
        }
        Date now = new Date();
        // 初始化店铺信息
        ShopDetail shopDetail = new ShopDetail();
        // 状态为开店申请中
        shopDetail.setShopStatus(ShopStatus.APPLYING.value());
        shopDetail.setCreateTime(now);
        shopDetail.setUpdateTime(now);
        // 店铺接收短信通知手机号
        shopDetail.setReceiveMobile(shopEmployee.getMobile());
        shopDetailService.save(shopDetail);
        // 创建商家账号
        shopEmployee.setShopId(shopDetail.getShopId());
        shopEmployee.setType(PositionType.ADMIN.value());
        shopEmployee.setNickname(shopEmployee.getUsername());
        String password = passwordEncoder.encode(passwordManager.decryptPassword(shopEmployee.getPassword()));
        shopEmployee.setPassword(password);
        shopEmployee.setStatus(1);
        shopEmployee.setCreateTime(now);
        shopEmployeeMapper.insert(shopEmployee);
        // 店铺更新店长id
        shopDetailService.update(Wrappers.lambdaUpdate(ShopDetail.class).set(ShopDetail::getUserId, shopEmployee.getEmployeeId()).eq(ShopDetail::getShopId, shopDetail.getShopId()));
        return shopEmployee;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeEmployeesByIds(List<Long> employeeIds) {
        shopEmployeeRoleMapper.deleteByEmployeeIds(employeeIds);
        removeByIds(employeeIds);
    }
    @Override
    public ShopEmployee getMerchantInfoByShopId(Long shopId) {
        return shopEmployeeMapper.getMerchantInfoByShopId(shopId);
    }
    @Override
    public void updateMerchantInfo(ShopEmployee shopEmployee) {
        if (Objects.isNull(shopEmployee.getShopId())) {
            throw new YamiShopBindException("店铺id不能为空");
        }
        ShopEmployee dbShopEmployee = shopEmployeeMapper.selectOne(Wrappers.lambdaQuery(ShopEmployee.class).eq(ShopEmployee::getShopId, shopEmployee.getShopId()).eq(ShopEmployee::getType, PositionType.ADMIN.value()));
        shopEmployee.setEmployeeId(dbShopEmployee.getEmployeeId());
        this.checkRegisterInfo(shopEmployee);
        if (Objects.nonNull(shopEmployee.getPassword())){
            shopEmployee.setPassword(passwordEncoder.encode(shopEmployee.getPassword()));
        }
        shopEmployeeMapper.updateById(shopEmployee);
    }
    @Override
    public List<ShopEmployee> listByParam(ShopEmployee shopEmployee) {
        return shopEmployeeMapper.listByParam(shopEmployee);
    }
    @Override
    public Long getShopEmployeeByUserId(Long id) {
        return shopEmployeeMapper.selectByUserId(id);
    }
    @Override
    public Integer getShopEmployeeCountByShopId(Long shopId) {
        return shopEmployeeMapper.selectEmployeeCount(shopId);
    }
    /**
     * 校验注册信息
     * @param shopEmployee
     * @return
     */
    private void checkRegisterInfo(ShopEmployee shopEmployee) {
        if (Objects.nonNull(shopEmployee.getMobile())) {
            // 手机号
            ShopEmployee getByMobile = shopEmployeeMapper.selectOne(Wrappers.lambdaQuery(ShopEmployee.class).eq(ShopEmployee::getMobile, shopEmployee.getMobile()));
            if (Objects.nonNull(getByMobile) && !Objects.equals(shopEmployee.getEmployeeId(), getByMobile.getEmployeeId())) {
                throw new YamiShopBindException("yami.phone.number.already.exists");
            }
        }
        if (Objects.nonNull(shopEmployee.getUsername())) {
            // 用户名
            ShopEmployee getByUsername = shopEmployeeMapper.selectOne(Wrappers.lambdaQuery(ShopEmployee.class).eq(ShopEmployee::getUsername,shopEmployee.getUsername()));
            if (Objects.nonNull(getByUsername) && !Objects.equals(shopEmployee.getEmployeeId(), getByUsername.getEmployeeId())) {
                throw new YamiShopBindException("yami.user.account.exist");
            }
        }
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopMenuServiceImpl.java
New file
@@ -0,0 +1,166 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.PositionType;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.sys.common.dao.ShopEmployeeMapper;
import com.yami.shop.sys.common.dao.ShopMenuMapper;
import com.yami.shop.sys.common.dao.ShopRoleMenuMapper;
import com.yami.shop.sys.common.model.ShopEmployee;
import com.yami.shop.sys.common.model.ShopMenu;
import com.yami.shop.sys.common.service.ShopMenuService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 菜单管理
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Service
@AllArgsConstructor
public class ShopMenuServiceImpl extends ServiceImpl<ShopMenuMapper, ShopMenu> implements ShopMenuService {
    private final ShopMenuMapper shopMenuMapper;
    private final ShopRoleMenuMapper shopRoleMenuMapper;
    private final ShopEmployeeMapper shopEmployeeMapper;
    @Override
    public List<ShopMenu> listMenuAndBtn(Long employeeId) {
        ShopEmployee shopEmployee = shopEmployeeMapper.selectById(employeeId);
        if (Objects.equals(PositionType.ADMIN.value(),shopEmployee.getType())){
            return shopMenuMapper.listMenuAndBtn(I18nMessage.getLang());
        }else {
            return shopMenuMapper.listRoleMenuAndBtn(I18nMessage.getLang(),employeeId);
        }
    }
    @Override
    public List<ShopMenu> listSimpleMenuNoButton() {
        return shopMenuMapper.listSimpleMenuNoButton(I18nMessage.getLang());
    }
    @Override
    public List<ShopMenu> listRootMenu() {
       return shopMenuMapper.listRootMenu(I18nMessage.getLang());
    }
    @Override
    public List<ShopMenu> listChildrenMenuByParentId(Long parentId) {
        return shopMenuMapper.listChildrenMenuByParentId(parentId,I18nMessage.getLang());
    }
    @Override
    public void deleteMenuAndRoleMenu(Long menuId) {
        //删除菜单
        this.removeById(menuId);
        //删除菜单与角色关联
        shopRoleMenuMapper.deleteByMenuId(menuId);
    }
    @Override
    public List<ShopMenu> listMenuByEmployeeId(Long employeeId) {
        // 用户的所有菜单信息
        List<ShopMenu> shopMenus;
        //商铺超级管理员,拥有最高权限
        ShopEmployee shopEmployee = shopEmployeeMapper.selectById(employeeId);
        if(Objects.equals(PositionType.ADMIN.value(),shopEmployee.getType())){
            shopMenus = shopMenuMapper.listMenu(I18nMessage.getLang());
        }else {
            shopMenus = shopMenuMapper.listMenuByEmployeeId(employeeId,I18nMessage.getLang());
        }
        //List<ShopMenu> rootMenu = getTree(shopMenus, 0l);
        Map<Long, List<ShopMenu>> sysMenuLevelMap = shopMenus.stream().sorted(Comparator.comparing(ShopMenu::getOrderNum))
                .collect(Collectors.groupingBy(ShopMenu::getParentId));
        // 一级菜单
        List<ShopMenu> rootMenu = sysMenuLevelMap.get(0L);
        if (CollectionUtil.isEmpty(rootMenu)) {
            return Collections.emptyList();
        }
        // 二三级菜单
        for (ShopMenu sysMenu : rootMenu) {
            List<ShopMenu> secondList = sysMenuLevelMap.get(sysMenu.getMenuId());
            if (CollectionUtil.isEmpty(secondList)){
                sysMenu.setList(secondList);
                continue;
            }
            for (ShopMenu secondMenu : secondList) {
                secondMenu.setList(sysMenuLevelMap.get(secondMenu.getMenuId()));
            }
            sysMenu.setList(secondList);
        }
        return rootMenu;
    }
    public List<ShopMenu> getTree(List<ShopMenu> sysMenus, Long id){
        List<ShopMenu> list = new ArrayList<>();
        for (ShopMenu shopMenu : sysMenus) {
            if (shopMenu.getParentId() == id) {
                list.add(shopMenu);
            }
        }
        //递归
        for (ShopMenu shopMenu  : list) {
            shopMenu.setList(getTree(sysMenus, shopMenu.getMenuId()));// .setChildrenMenuList();
        }
        if (list.size() == 0) {
            return null;//new ArrayList<SysMenu>();
        }
        return list;
    }
    @Override
    public List<Long> listMenuIdByRoleId(Long roleId) {
        return shopMenuMapper.listMenuIdByRoleId(roleId);
    }
    @Override
    public Set<String> updateSonMenuState(Long parentId, Integer state) {
        shopMenuMapper.updateSonMenuState(parentId,state);
        return shopMenuMapper.listMenuPerms(parentId);
    }
    @Override
    public Set<String> listConcealButtonPerms() {
        return shopMenuMapper.listConcealButtonPerms();
    }
    @Override
    public Set<String> getShopPermissions(ShopEmployee shopEmployee) {
        Integer type = shopEmployee.getType();
        Long employeeId = shopEmployee.getEmployeeId();
        List<String> permsList;
        //店铺超级管理员,拥有最高权限
        if(Objects.equals(PositionType.ADMIN.value(),type)){
            List<ShopMenu> menuList = shopMenuMapper.selectList(Wrappers.emptyWrapper());
            permsList = menuList.stream().map(ShopMenu::getPerms).collect(Collectors.toList());
        }else{
            permsList = shopEmployeeMapper.queryAllPerms(employeeId);
        }
        return permsList.stream().flatMap((perms)->{
            if (StrUtil.isBlank(perms)) {
                return null;
            }
            return Arrays.stream(perms.trim().split(StrUtil.COMMA));
        }).collect(Collectors.toSet());
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopRoleMenuServiceImpl.java
New file
@@ -0,0 +1,29 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.sys.common.dao.ShopRoleMenuMapper;
import com.yami.shop.sys.common.model.ShopRoleMenu;
import com.yami.shop.sys.common.service.ShopRoleMenuService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
/**
 * 角色与菜单对应关系
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Service
@AllArgsConstructor
public class ShopRoleMenuServiceImpl extends ServiceImpl<ShopRoleMenuMapper, ShopRoleMenu> implements ShopRoleMenuService {
    private final ShopRoleMenuMapper shopRoleMenuMapper;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/ShopRoleServiceImpl.java
New file
@@ -0,0 +1,103 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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.extension.service.impl.ServiceImpl;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.sys.common.dao.ShopEmployeeRoleMapper;
import com.yami.shop.sys.common.dao.ShopRoleMapper;
import com.yami.shop.sys.common.dao.ShopRoleMenuMapper;
import com.yami.shop.sys.common.model.ShopRole;
import com.yami.shop.sys.common.service.ShopRoleService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 角色
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Service
@AllArgsConstructor
public class ShopRoleServiceImpl extends ServiceImpl<ShopRoleMapper, ShopRole> implements ShopRoleService {
    private final ShopRoleMapper shopRoleMapper;
    private final ShopRoleMenuMapper shopRoleMenuMapper;
    private final ShopEmployeeRoleMapper shopEmployeeRoleMapper;
    @Override
    public Boolean saveRoleAndRoleMenu(ShopRole shopRole) {
        shopRole.setCreateTime(new Date());
        this.save(shopRole);
        if (CollectionUtil.isEmpty(shopRole.getMenuIdList())) {
            return true;
        }
        //保存角色与菜单关系
        shopRoleMenuMapper.insertRoleAndRoleMenu(shopRole.getRoleId(), shopRole.getMenuIdList());
        return true;
    }
    @Override
    public Boolean updateRoleAndRoleMenu(ShopRole shopRole) {
        // 更新角色
        shopRoleMapper.updateById(shopRole);
        //先删除角色与菜单关系
        shopRoleMenuMapper.deleteBatch(Collections.singletonList(shopRole.getRoleId()));
        if (CollectionUtil.isEmpty(shopRole.getMenuIdList())) {
            return true;
        }
        //保存角色与菜单关系
        shopRoleMenuMapper.insertRoleAndRoleMenu(shopRole.getRoleId(), shopRole.getMenuIdList());
        return true;
    }
    @Override
    public Boolean deleteBatch(Long[] ids) {
        List<Long> roleIds = CollUtil.newArrayList(ids);
        // 获取正在使用中的角色
        List<Long> userRoleIds = shopEmployeeRoleMapper.selectUseRoleIds(roleIds);
        if (CollUtil.isNotEmpty(userRoleIds)) {
            List<ShopRole> sysRoles = list(new LambdaQueryWrapper<ShopRole>().select(ShopRole::getRoleName).in(ShopRole::getRoleId, userRoleIds));
            List<String> names = sysRoles.stream().map(ShopRole::getRoleName).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(names)) {
                String message = I18nMessage.getMessage("yami.role.use.cannot.deleted");
                throw new YamiShopBindException(message + names);
            }
        }
        //删除角色
        shopRoleMapper.deleteBatch(roleIds);
        //删除角色与菜单关联
        shopRoleMenuMapper.deleteBatch(roleIds);
        //删除角色与用户关联
        shopEmployeeRoleMapper.deleteBatch(roleIds);
        return true;
    }
    @Override
    public List<Long> listRoleIdByEmployeeId(Long employeeId) {
        return shopRoleMapper.listRoleIdByEmployeeId(employeeId);
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysLogServiceImpl.java
New file
@@ -0,0 +1,27 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.sys.common.dao.SysLogMapper;
import com.yami.shop.sys.common.model.SysLog;
import com.yami.shop.sys.common.service.SysLogService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
/**
 * @author lgh
 */
@Service("sysLogService")
@AllArgsConstructor
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {
    private final SysLogMapper sysLogMapper;
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysMenuServiceImpl.java
New file
@@ -0,0 +1,129 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.sys.common.dao.SysMenuMapper;
import com.yami.shop.sys.common.dao.SysRoleMenuMapper;
import com.yami.shop.sys.common.model.SysMenu;
import com.yami.shop.sys.common.service.SysMenuService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author lgh
 */
@Service("sysMenuService")
@AllArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    private final SysRoleMenuMapper sysRoleMenuMapper;
    private final SysMenuMapper sysMenuMapper;
    @Override
    public List<SysMenu> listMenuByUserId(Long userId) {
        // 用户的所有菜单信息
        List<SysMenu> sysMenus ;
        //系统管理员,拥有最高权限
        if(userId == Constant.SUPER_ADMIN_ID){
            sysMenus = sysMenuMapper.listMenu(I18nMessage.getLang());
        }else {
            sysMenus = sysMenuMapper.listMenuByUserId(userId,I18nMessage.getLang());
        }
        Map<Long, List<SysMenu>> sysMenuLevelMap = sysMenus.stream()
                .sorted(Comparator.comparing(SysMenu::getOrderNum))
                .collect(Collectors.groupingBy(SysMenu::getParentId));
        // 一级菜单
        List<SysMenu> rootMenu = sysMenuLevelMap.get(0L);
        if (CollectionUtil.isEmpty(rootMenu)) {
            return Collections.emptyList();
        }
        // 二三级菜单
        for (SysMenu sysMenu : rootMenu) {
            List<SysMenu> secondList = sysMenuLevelMap.get(sysMenu.getMenuId());
            if (CollectionUtil.isEmpty(secondList)){
                sysMenu.setList(secondList);
                continue;
            }
            for (SysMenu secondMenu : secondList) {
                secondMenu.setList(sysMenuLevelMap.get(secondMenu.getMenuId()));
            }
            sysMenu.setList(secondList);
        }
        return rootMenu;
    }
    @Override
    public void deleteMenuAndRoleMenu(Long menuId){
        //删除菜单
        this.removeById(menuId);
        //删除菜单与角色关联
        sysRoleMenuMapper.deleteByMenuId(menuId);
    }
    @Override
    public List<Long> listMenuIdByRoleId(Long roleId) {
        return sysMenuMapper.listMenuIdByRoleId(roleId);
    }
    @Override
    public List<SysMenu> listSimpleMenuNoButton() {
        return sysMenuMapper.listSimpleMenuNoButton(I18nMessage.getLang());
    }
    @Override
    public List<SysMenu> listRootMenu() {
        return sysMenuMapper.listRootMenu(I18nMessage.getLang());
    }
    @Override
    public List<SysMenu> listChildrenMenuByParentId(Long parentId) {
        return sysMenuMapper.listChildrenMenuByParentId(parentId,I18nMessage.getLang());
    }
    @Override
    public List<SysMenu> listMenuAndBtn(Long userId) {
        //系统管理员,拥有最高权限
        if (userId == Constant.SUPER_ADMIN_ID){
            return sysMenuMapper.listMenuAndBtn(I18nMessage.getLang());
        }else {
            return sysMenuMapper.listRoleMenuAndBtn(I18nMessage.getLang(),userId);
        }
    }
    @Override
    public Set<String> updateSonMenuState(Long menuId, Integer state) {
//        List<SysMenu> sysMenus = sysMenuMapper.selectList(new QueryWrapper<SysMenu>().eq("menu_id", menuId));
//        sysMenuMapper.update(new SysMenu(),new QueryWrapper<SysMenu>().eq("parent_id",menuId));
        sysMenuMapper.updateSonMenuState(menuId,state);
        Set<String> perms = sysMenuMapper.listMenuPerms(menuId);
        return perms;
    }
    @Override
    public Set<String> listConcealButtonPerms() {
        return sysMenuMapper.listConcealButtonPerms();
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysRoleServiceImpl.java
New file
@@ -0,0 +1,101 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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.extension.service.impl.ServiceImpl;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.sys.common.dao.SysRoleMapper;
import com.yami.shop.sys.common.dao.SysRoleMenuMapper;
import com.yami.shop.sys.common.dao.SysUserRoleMapper;
import com.yami.shop.sys.common.model.SysRole;
import com.yami.shop.sys.common.service.SysRoleService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 角色
 * @author lgh
 */
@Service("sysRoleService")
@AllArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    private final SysRoleMenuMapper sysRoleMenuMapper;
    private final SysUserRoleMapper sysUserRoleMapper;
    private final SysRoleMapper sysRoleMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRoleAndRoleMenu(SysRole role) {
        role.setCreateTime(new Date());
        this.save(role);
        if (CollectionUtil.isEmpty(role.getMenuIdList())) {
            return;
        }
        //保存角色与菜单关系
        sysRoleMenuMapper.insertRoleAndRoleMenu(role.getRoleId(), role.getMenuIdList());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRoleAndRoleMenu(SysRole role) {
        // 更新角色
        sysRoleMapper.updateById(role);
        //先删除角色与菜单关系
        sysRoleMenuMapper.deleteBatch(Collections.singletonList(role.getRoleId()));
        if (CollectionUtil.isEmpty(role.getMenuIdList())) {
            return;
        }
        //保存角色与菜单关系
        sysRoleMenuMapper.insertRoleAndRoleMenu(role.getRoleId(), role.getMenuIdList());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Long> roleIds) {
        // 获取正在使用中的角色
        List<Long> userRoleIds = sysUserRoleMapper.selectUseRoleIds(roleIds);
        if (CollUtil.isNotEmpty(userRoleIds)) {
            List<SysRole> sysRoles = list(new LambdaQueryWrapper<SysRole>().select(SysRole::getRoleName).in(SysRole::getRoleId, userRoleIds));
            List<String> names = sysRoles.stream().map(SysRole::getRoleName).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(names)) {
                String message = I18nMessage.getMessage("yami.role.use.cannot.deleted");
                throw new YamiShopBindException(message + names);
            }
        }
        //删除角色
        sysRoleMapper.deleteBatch(roleIds);
        //删除角色与菜单关联
        sysRoleMenuMapper.deleteBatch(roleIds);
        //删除角色与用户关联
        sysUserRoleMapper.deleteBatch(roleIds);
    }
    @Override
    public List<Long> listRoleIdByUserId(Long userId) {
        return sysRoleMapper.listRoleIdByUserId(userId);
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/java/com/yami/shop/sys/common/service/impl/SysUserServiceImpl.java
New file
@@ -0,0 +1,88 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.common.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.config.Constant;
import com.yami.shop.sys.common.dao.SysUserMapper;
import com.yami.shop.sys.common.dao.SysUserRoleMapper;
import com.yami.shop.sys.common.model.SysUser;
import com.yami.shop.sys.common.service.SysUserService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
 * 系统用户
 * @author lgh
 */
@Service("sysUserService")
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    private SysUserRoleMapper sysUserRoleMapper;
    private SysUserMapper sysUserMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUserAndUserRole(SysUser user) {
        user.setCreateTime(new Date());
        sysUserMapper.insert(user);
        if(CollUtil.isEmpty(user.getRoleIdList())){
            return ;
        }
        //保存用户与角色关系
        sysUserRoleMapper.insertUserAndUserRole(user.getUserId(), user.getRoleIdList());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserAndUserRole(SysUser user) {
        // 超级管理员的用户名不做修改
        if (user.getUserId() == Constant.SUPER_ADMIN_ID) {
            user.setUsername(null);
        }
        // 更新用户
        sysUserMapper.updateById(user);
        //先删除用户与角色关系
        sysUserRoleMapper.deleteByUserId(user.getUserId());
        if(CollUtil.isEmpty(user.getRoleIdList())){
            return ;
        }
        //保存用户与角色关系
        sysUserRoleMapper.insertUserAndUserRole(user.getUserId(), user.getRoleIdList());
    }
    @Override
    public void updatePasswordByUserId(Long userId, String newPassword) {
        SysUser user = new SysUser();
        user.setPassword(newPassword);
        user.setUserId(userId);
        sysUserMapper.updateById(user);
    }
    @Override
    public SysUser getByUserName(String username) {
        return sysUserMapper.selectByUsername(username);
    }
    @Override
    public SysUser getSysUserById(Long userId) {
        return sysUserMapper.selectById(userId);
    }
}
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopEmployeeMapper.xml
New file
@@ -0,0 +1,58 @@
<?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.sys.common.dao.ShopEmployeeMapper">
  <resultMap id="shopEmployeeMap" type="com.yami.shop.sys.common.model.ShopEmployee">
    <id column="employee_id" property="employeeId" />
    <result column="shop_id" property="shopId"/>
    <result column="type" property="type"/>
    <result column="mobile" property="mobile"/>
    <result column="username" property="username"/>
    <result column="nickname" property="nickname"/>
    <result column="password" property="password"/>
    <result column="email" property="email"/>
    <result column="status" property="status"/>
    <result column="create_employee_id" property="createEmployeeId"/>
    <result column="create_time" property="createTime"/>
  </resultMap>
    <select id="getShopByUsernameOrMobile" resultType="com.yami.shop.sys.common.model.ShopEmployee"
            parameterType="java.lang.String">
        SELECT se.*,sd.`shop_status`
        FROM tz_shop_employee se
        LEFT JOIN `tz_shop_detail` sd ON sd.`shop_id` =  se.`shop_id`
        WHERE se.username = #{username} OR se.mobile = #{username}
    </select>
    <select id="queryAllPerms" resultType="java.lang.String" parameterType="java.lang.Long">
        SELECT m.perms
        FROM tz_shop_employee_role er
        LEFT JOIN tz_shop_role_menu rm ON er.role_id = rm.role_id
        LEFT JOIN tz_shop_menu m ON rm.menu_id = m.menu_id
        WHERE er.employee_id = #{employeeId}
    </select>
    <select id="getByUserName" resultType="com.yami.shop.sys.common.model.ShopEmployee"
            parameterType="java.lang.String">
        SELECT * FROM tz_shop_employee WHERE username = #{username}
    </select>
    <select id="getMerchantInfoByShopId" resultType="com.yami.shop.sys.common.model.ShopEmployee">
        SELECT se.*, sd.shop_name
        FROM tz_shop_employee se
        JOIN `tz_shop_detail` sd ON se.shop_id = sd.shop_id
        WHERE se.type = 0 AND se.shop_id = #{shopId}
    </select>
    <select id="listByParam" resultType="com.yami.shop.sys.common.model.ShopEmployee">
        SELECT se.employee_id, se.type, se.nickname, se.mobile, se.username, se.email, se.status
        FROM tz_shop_employee se
        <where>
            <if test="shopEmployee.shopId != null">
                AND se.shop_id = #{shopEmployee.shopId}
            </if>
            <if test="shopEmployee.type != null">
                AND se.type = #{shopEmployee.type}
            </if>
            <if test="shopEmployee.status != null">
                AND se.status = #{shopEmployee.status}
            </if>
        </where>
    </select>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopEmployeeRoleMapper.xml
New file
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.sys.common.dao.ShopEmployeeRoleMapper">
  <resultMap id="shopEmployeeRoleMap" type="com.yami.shop.sys.common.model.ShopEmployeeRole">
    <id column="id" property="id" />
    <result column="employee_id" property="employeeId"/>
    <result column="role_id" property="roleId"/>
  </resultMap>
  <insert id="insertUserAndUserRole">
    insert into tz_shop_employee_role (employee_id,role_id) values
    <foreach collection="roleIdList" item="roleId" separator=",">
      (#{employeeId},#{roleId})
    </foreach>
  </insert>
  <delete id="deleteBatch">
    delete from tz_shop_employee_role where role_id in
    <foreach item="roleId" collection="roleIds" open="(" separator="," close=")">
      #{roleId}
    </foreach>
  </delete>
  <delete id="deleteByEmployeeId" parameterType="java.lang.Long">
    delete from tz_shop_employee_role where employee_id = #{employeeId}
  </delete>
  <delete id="deleteByEmployeeIds">
    delete from tz_shop_employee_role where employee_id in
    <foreach collection="employeeIds" open="(" separator="," close=")" item="employeeId">
      #{employeeId}
    </foreach>
  </delete>
  <select id="selectUseRoleIds" resultType="java.lang.Long">
    select role_id from tz_shop_employee_role where role_id in
    <foreach collection="roleIds" item="roleId" open="(" close=")" separator=",">
      #{roleId}
    </foreach>
  </select>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopMenuMapper.xml
New file
@@ -0,0 +1,113 @@
<?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.sys.common.dao.ShopMenuMapper">
  <resultMap id="shopMenuMap" type="com.yami.shop.sys.common.model.ShopMenu">
    <id column="menu_id" property="menuId" />
    <result column="parent_id" property="parentId"/>
    <result column="name" property="name"/>
    <result column="url" property="url"/>
    <result column="perms" property="perms"/>
    <result column="type" property="type"/>
    <result column="icon" property="icon"/>
    <result column="order_num" property="orderNum"/>
    <result column="name_en" property="nameEn"/>
  </resultMap>
    <select id="listMenuAndBtn" resultType="com.yami.shop.sys.common.model.ShopMenu"
            parameterType="java.lang.Integer">
      SELECT menu_id,parent_id,name_en,
      <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
      <if test="lang!=1">`name`</if>
      ,url,perms,`type`,icon,order_num,hidden
      FROM tz_shop_menu
      order by order_num
    </select>
  <select id="listSimpleMenuNoButton" resultType="com.yami.shop.sys.common.model.ShopMenu"
          parameterType="java.lang.Integer">
    select menu_id ,parent_id ,name_en,
    <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
    <if test="lang!=1">`name`</if>
    from tz_shop_menu
    where `type` != 2
    order by order_num
  </select>
  <select id="listRootMenu" resultType="com.yami.shop.sys.common.model.ShopMenu" parameterType="java.lang.Integer">
    select menu_id,name_en,
    <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
    <if test="lang!=1">`name`</if>
    from tz_shop_menu
    where `type` = 0
  </select>
  <select id="listChildrenMenuByParentId" resultType="com.yami.shop.sys.common.model.ShopMenu">
    select menu_id,name_en,
    <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
    <if test="lang!=1">`name`</if>
    from tz_shop_menu
    where parent_id = #{parentId}
  </select>
  <!-- 查询所有菜单 -->
  <select id="listMenu" resultType="com.yami.shop.sys.common.model.ShopMenu"
          parameterType="java.lang.Integer">
    SELECT menu_id,parent_id,name_en,
    <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
    <if test="lang!=1">`name`</if>
    ,url,perms,`type`,icon,order_num,hidden FROM tz_shop_menu
    WHERE `type` != 2 ORDER BY order_num
  </select>
  <!-- 查询用户的所有菜单 -->
  <select id="listMenuByEmployeeId" resultType="com.yami.shop.sys.common.model.ShopMenu">
    SELECT DISTINCT m.menu_id AS menu_id,m.parent_id,m.name_en,
    <if test="lang==1">IFNULL(m.name_en,m.name) AS name</if>
    <if test="lang!=1">m.name</if>
    ,url,m.type,m.icon,m.order_num,m.hidden
    FROM tz_shop_employee_role er
    LEFT JOIN tz_shop_role_menu rm ON er.role_id = rm.role_id
    LEFT JOIN tz_shop_menu m ON m.`menu_id` = rm.`menu_id`
    WHERE er.employee_id = #{employeeId} and m.type != 2
    order by order_num
  </select>
    <select id="listMenuIdByRoleId" resultType="java.lang.Long" parameterType="java.lang.Long">
      select menu_id from tz_shop_role_menu where role_id = #{roleId}
    </select>
  <select id="listMenuNameByPerms" resultType="java.lang.String">
    SELECT
    <if test="lang != 1">
      `name`
    </if>
    <if test="lang == 1">
      name_en
    </if>
    FROM tz_shop_menu
    WHERE menu_id IN (SELECT DISTINCT parent_id FROM tz_shop_menu WHERE perms LIKE CONCAT('%', #{perms}, '%'))
  </select>
  <update id="updateSonMenuState">
    UPDATE tz_shop_menu SET hidden = #{state} WHERE parent_id = #{parentId}
  </update>
  <select id="listConcealButtonPerms" resultType="java.lang.String">
    SELECT perms FROM tz_shop_menu WHERE hidden = 1
  </select>
  <select id="listMenuPerms" resultType="java.lang.String">
    SELECT perms FROM tz_shop_menu WHERE parent_id = #{parentId} AND type = 2
  </select>
  <select id="listRoleMenuAndBtn" resultType="com.yami.shop.sys.common.model.ShopMenu">
    SELECT menu_id,parent_id,name_en,
    <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
    <if test="lang!=1">`name`</if>
    ,url,perms,`type`,icon,order_num,hidden
    FROM tz_shop_menu
    WHERE menu_id IN
    (
    SELECT sm.menu_id FROM tz_shop_role_menu AS rm INNER JOIN tz_shop_menu AS sm ON rm.menu_id = sm.menu_id WHERE rm.role_id IN
        (SELECT role_id FROM tz_shop_employee AS se INNER JOIN tz_shop_employee_role AS er ON se.employee_id = er.employee_id WHERE se.employee_id = #{employeeId})
    )
    order by order_num
  </select>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopRoleMapper.xml
New file
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.sys.common.dao.ShopRoleMapper">
  <resultMap id="shopRoleMap" type="com.yami.shop.sys.common.model.ShopRole">
    <id column="role_id" property="roleId" />
    <id column="shop_id" property="shopId" />
    <result column="role_name" property="roleName"/>
    <result column="remark" property="remark"/>
    <result column="create_user_id" property="createEmployeeId"/>
    <result column="create_time" property="createTime"/>
  </resultMap>
    <delete id="deleteBatch">
      delete from tz_shop_role where role_id in
      <foreach collection="roleIds" item="roleId" index="no" open="("
               separator="," close=")">
        #{roleId}
      </foreach>
    </delete>
  <select id="listRoleIdByEmployeeId" resultType="java.lang.Long" parameterType="java.lang.Long">
    select role_id from tz_shop_employee_role where employee_id = #{employeeId}
  </select>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/ShopRoleMenuMapper.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.sys.common.dao.ShopRoleMenuMapper">
  <resultMap id="shopRoleMenuMap" type="com.yami.shop.sys.common.model.ShopRoleMenu">
    <id column="id" property="id" />
    <result column="role_id" property="roleId"/>
    <result column="menu_id" property="menuId"/>
  </resultMap>
    <insert id="insertRoleAndRoleMenu">
      insert into tz_shop_role_menu (role_id,menu_id) values
      <foreach collection="menuIdList" item="menuId" separator=",">
        (#{roleId},#{menuId})
      </foreach>
    </insert>
    <delete id="deleteByMenuId" parameterType="java.lang.Long">
      delete from tz_shop_role_menu where menu_id = #{menuId}
    </delete>
  <delete id="deleteBatch">
    delete from tz_shop_role_menu where role_id in
    <foreach item="roleId" collection="roleIds" open="(" separator="," close=")">
      #{roleId}
    </foreach>
  </delete>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysLogMapper.xml
New file
@@ -0,0 +1,7 @@
<?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.sys.common.dao.SysLogMapper">
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysMenuMapper.xml
New file
@@ -0,0 +1,92 @@
<?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.sys.common.dao.SysMenuMapper">
    <select id="listMenuIdByRoleId" resultType="java.lang.Long">
        select menu_id from tz_sys_role_menu where role_id = #{roleId}
    </select>
    <!-- 查询用户的所有菜单 -->
    <select id="listMenuByUserId" resultType="com.yami.shop.sys.common.model.SysMenu">
        SELECT DISTINCT m.menu_id AS menu_id,m.parent_id,m.name_en,
        <if test="lang==1">IFNULL(m.name_en,m.name) AS name</if>
        <if test="lang!=1">m.name</if>
        ,url,m.type,m.icon,m.order_num,m.hidden FROM tz_sys_user_role ur
        LEFT JOIN tz_sys_role_menu rm ON ur.role_id = rm.role_id LEFT JOIN tz_sys_menu m ON m.`menu_id` = rm.`menu_id`
        WHERE ur.user_id = #{userId} and m.type != 2 order by order_num
    </select>
    <!-- 查询所有菜单 -->
    <select id="listMenu" resultType="com.yami.shop.sys.common.model.SysMenu">
        SELECT menu_id,parent_id,name_en,
        <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
        <if test="lang!=1">`name`</if>
        ,url,perms,`type`,icon,order_num,hidden FROM tz_sys_menu WHERE `type` != 2 ORDER BY order_num
    </select>
    <select id="listSimpleMenuNoButton" resultType="com.yami.shop.sys.common.model.SysMenu">
        select menu_id ,parent_id ,name_en,
        <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
        <if test="lang!=1">`name`</if>
        from tz_sys_menu where `type` != 2 order by order_num
    </select>
    <select id="listRootMenu" resultType="com.yami.shop.sys.common.model.SysMenu">
        select menu_id,name_en,
        <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
        <if test="lang!=1">`name`</if>
        from tz_sys_menu where `type` = 0
    </select>
    <select id="listChildrenMenuByParentId" resultType="com.yami.shop.sys.common.model.SysMenu">
        select menu_id,name_en,
        <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
        <if test="lang!=1">`name`</if>
        from tz_sys_menu where parent_id = #{parentId}
    </select>
    <select id="listMenuAndBtn" resultType="com.yami.shop.sys.common.model.SysMenu">
        SELECT menu_id,parent_id,name_en,
        <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
        <if test="lang!=1">`name`</if>
        ,url,perms,`type`,icon,order_num,hidden FROM tz_sys_menu order by order_num
    </select>
    <select id="listMenuNameByPerms" resultType="java.lang.String">
        SELECT
        <if test="lang != 1">
            `name`
        </if>
        <if test="lang == 1">
            name_en
        </if>
        FROM tz_sys_menu
        WHERE menu_id IN (SELECT DISTINCT parent_id FROM tz_sys_menu WHERE perms LIKE CONCAT('%', #{perms}, '%'))
    </select>
    <update id="updateSonMenuState">
        UPDATE tz_sys_menu SET hidden = #{state} WHERE parent_id = #{parentId}
    </update>
    <select id="listMenuPerms" resultType="java.lang.String">
        SELECT perms FROM tz_sys_menu WHERE parent_id = #{parentId} AND type = 2
    </select>
    <select id="listConcealButtonPerms" resultType="java.lang.String">
        SELECT perms FROM tz_sys_menu WHERE hidden = 1
    </select>
    <select id="listRoleMenuAndBtn" resultType="com.yami.shop.sys.common.model.SysMenu">
        SELECT menu_id,parent_id,name_en,
        <if test="lang==1">IFNULL(name_en,`name`) AS name</if>
        <if test="lang!=1">`name`</if>
        ,url,perms,`type`,icon,order_num,hidden FROM tz_sys_menu
        WHERE
        menu_id IN
        (
        SELECT sm.menu_id FROM tz_sys_role_menu AS rm INNER JOIN tz_sys_menu AS sm ON rm.menu_id = sm.menu_id WHERE rm.role_id IN
            (SELECT role_id FROM tz_sys_user AS su INNER JOIN tz_sys_user_role AS ur ON su.user_id = ur.user_id WHERE su.user_id = #{userId})
        )
    </select>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysRoleMapper.xml
New file
@@ -0,0 +1,17 @@
<?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.sys.common.dao.SysRoleMapper">
    <delete id="deleteBatch"  parameterType="java.lang.Long">
        delete from tz_sys_role where role_id in
          <foreach collection="roleIds" item="roleId" index="no" open="("
            separator="," close=")">
            #{roleId}
        </foreach>
    </delete>
    <select id="listRoleIdByUserId" resultType="java.lang.Long">
        select role_id from tz_sys_user_role where user_id = #{userId}
    </select>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysRoleMenuMapper.xml
New file
@@ -0,0 +1,23 @@
<?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.sys.common.dao.SysRoleMenuMapper">
    <delete id="deleteBatch">
        delete from tz_sys_role_menu where role_id in
        <foreach item="roleId" collection="roleIds" open="(" separator="," close=")">
            #{roleId}
        </foreach>
    </delete>
    <delete id="deleteByMenuId">
        delete from tz_sys_role_menu where menu_id = #{menuId}
    </delete>
    <insert id="insertRoleAndRoleMenu">
        insert into tz_sys_role_menu (role_id,menu_id) values
          <foreach collection="menuIdList" item="menuId" separator=",">
              (#{roleId},#{menuId})
          </foreach>
    </insert>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysUserMapper.xml
New file
@@ -0,0 +1,17 @@
<?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.sys.common.dao.SysUserMapper">
    <!-- 查询用户的所有权限 -->
    <select id="queryAllPerms" resultType="string">
        select m.perms from tz_sys_user_role ur
            LEFT JOIN tz_sys_role_menu rm on ur.role_id = rm.role_id
            LEFT JOIN tz_sys_menu m on rm.menu_id = m.menu_id
        where ur.user_id = #{userId}
    </select>
    <select id="selectByUsername" resultType="com.yami.shop.sys.common.model.SysUser">
        select * from tz_sys_user where username = #{username}
    </select>
</mapper>
yami-shop-sys/yami-shop-sys-common/src/main/resources/mapper/SysUserRoleMapper.xml
New file
@@ -0,0 +1,30 @@
<?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.sys.common.dao.SysUserRoleMapper">
    <delete id="deleteBatch">
        delete from tz_sys_user_role where role_id in
        <foreach item="roleId" collection="roleIds" open="(" separator="," close=")">
            #{roleId}
        </foreach>
    </delete>
    <delete id="deleteByUserId">
        delete from tz_sys_user_role where user_id = #{userId}
    </delete>
    <insert id="insertUserAndUserRole">
          insert into tz_sys_user_role (user_id,role_id) values
          <foreach collection="roleIdList" item="roleId" separator=",">
              (#{userId},#{roleId})
          </foreach>
  </insert>
    <select id="selectUseRoleIds" resultType="java.lang.Long">
        select role_id from tz_sys_user_role where role_id in
        <foreach collection="roleIds" item="roleId" open="(" close=")" separator=",">
            #{roleId}
        </foreach>
    </select>
</mapper>
yami-shop-sys/yami-shop-sys-multishop/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-sys</artifactId>
        <groupId>com.yami.shop</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-sys-multishop</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-sys-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-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/adapter/MultishopSignAuthAdapter.java
New file
@@ -0,0 +1,63 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.multishop.adapter;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.enums.PositionType;
import com.yami.shop.common.config.Constant;
import com.yami.shop.security.common.adapter.SignAuthAdapter;
import com.yami.shop.security.common.bo.UserInfoInTokenBO;
import com.yami.shop.security.common.enums.SysTypeEnum;
import com.yami.shop.sys.common.dao.ShopEmployeeMapper;
import com.yami.shop.sys.common.dao.ShopMenuMapper;
import com.yami.shop.sys.common.model.ShopEmployee;
import com.yami.shop.sys.common.model.ShopMenu;
import com.yami.shop.sys.common.service.ShopMenuService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
 *
 * @author lgh on 2018/09/07.
 */
@Service
@AllArgsConstructor
public class MultishopSignAuthAdapter implements SignAuthAdapter {
    private final ShopMenuService shopMenuService;
    private final ShopEmployeeMapper shopEmployeeMapper;
    @Override
    public UserInfoInTokenBO loadUserInfoInToken(Map<String, Object> dataMap) {
        UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
        ShopEmployee shopEmployee;
        // 没有指定用户,默认为管理员
        long shopId = dataMap.get("shopId") == null ? Constant.MAIN_SHOP : (Long)dataMap.get("shopId");
        shopEmployee = shopEmployeeMapper.selectOne(new LambdaQueryWrapper<ShopEmployee>()
                .eq(ShopEmployee::getShopId, shopId)
                .eq(ShopEmployee::getType, 0)
        );
        userInfoInToken.setUserId(shopEmployee.getEmployeeId().toString());
        userInfoInToken.setSysType(SysTypeEnum.MULTISHOP.value());
        userInfoInToken.setEnabled(shopEmployee.getStatus() == 1);
        userInfoInToken.setShopId(shopEmployee.getShopId());
        userInfoInToken.setOtherId(shopEmployee.getEmployeeId());
        userInfoInToken.setPerms(shopMenuService.getShopPermissions(shopEmployee));
        return userInfoInToken;
    }
}
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,34 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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("sysSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi sysMallRestApi() {
        return GroupedOpenApi.builder()
                .group("系统配置")
                .packagesToScan("com.yami.shop.sys.multishop.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/ShopEmployeeController.java
New file
@@ -0,0 +1,269 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.multishop.controller;
import cn.hutool.core.collection.CollUtil;
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.core.toolkit.Wrappers;
import com.yami.shop.bean.enums.PositionType;
import com.yami.shop.common.annotation.SysLog;
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.security.common.enums.SysTypeEnum;
import com.yami.shop.security.common.manager.PasswordManager;
import com.yami.shop.security.common.manager.TokenStore;
import com.yami.shop.security.common.model.UpdatePasswordDto;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.sys.common.model.ShopEmployee;
import com.yami.shop.sys.common.service.ShopEmployeeService;
import com.yami.shop.sys.common.service.ShopRoleService;
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.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
/**
 * 商家端用户
 * @author cl
 * @date 2021-03-01 17:42:09
 */
@RestController
@RequestMapping("/sys/shopEmployee" )
@Tag(name = "商家端用户接口")
public class ShopEmployeeController {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    @Autowired
    private ShopEmployeeService shopEmployeeService;
    @Autowired
    private ShopRoleService shopRoleService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private PasswordManager passwordManager;
    /**
     * 分页查询
     * @param page 分页对象
     * @param shopEmployee 系统用户
     * @return 分页数据
     */
    @GetMapping("/page" )
    @Operation(summary = "分页获取用户" , description = "分页获取用户")
    public ServerResponseEntity<IPage<ShopEmployee>> getShopEmployeePage(PageParam<ShopEmployee> page, @ParameterObject ShopEmployee shopEmployee) {
        // 只显示店铺自己的管理员
        //ShopEmployee employee = shopEmployeeService.getShopEmployeeById(SecurityUtils.getShopUser().getEmployeeId());
        PageParam<ShopEmployee> resPage = shopEmployeeService.page(page, new LambdaQueryWrapper<ShopEmployee>()
                .eq(ShopEmployee::getShopId,SecurityUtils.getShopUser().getShopId())
                .like(StrUtil.isNotBlank(shopEmployee.getUsername()),ShopEmployee::getUsername,shopEmployee.getUsername())
                .like(StrUtil.isNotBlank(shopEmployee.getNickname()),ShopEmployee::getNickname,shopEmployee.getNickname()));
        for(ShopEmployee employee : resPage.getRecords()){
            if (BooleanUtil.isFalse(permission) && StrUtil.isNotBlank(employee.getMobile())) {
                employee.setMobile(PhoneUtil.hideBetween(employee.getMobile()).toString());
            }
        }
        return ServerResponseEntity.success(resPage);
    }
    /**
     * 获取登录的用户信息
     */
    @GetMapping("/info")
    @Operation(summary = "获取登录的用户信息" , description = "获取登录的用户信息")
    public ServerResponseEntity<ShopEmployee> info(){
        ShopEmployee employee = shopEmployeeService.getShopEmployeeById(SecurityUtils.getShopUser().getEmployeeId());
        if (Objects.isNull(employee)) {
            throw new YamiShopBindException("yami.shop.data.is.removed");
        }
        if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), employee.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        return ServerResponseEntity.success(employee);
    }
    /**
     * 修改登录用户密码
     */
    @SysLog("商家端-修改密码")
    @PostMapping("/password")
    @Operation(summary = "修改密码" , description = "修改当前登陆用户的密码")
    public ServerResponseEntity<String> password(@RequestBody @Valid UpdatePasswordDto param){
        Long employeeId = SecurityUtils.getShopUser().getEmployeeId();
        if (Objects.equals(employeeId.intValue(), Constant.SUPER_ADMIN_ID) && BooleanUtil.isFalse(permission)) {
            throw new YamiShopBindException("yami.no.auth");
        }
        ShopEmployee dbShopEmployee = shopEmployeeService.getShopEmployeeById(employeeId);
        String password = passwordManager.decryptPassword(param.getPassword());
        if (!passwordEncoder.matches(password, dbShopEmployee.getPassword())) {
            // 原密码不正确
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.password.error"));
        }
        //新密码
        String decryptPassword = passwordManager.decryptPassword(param.getNewPassword());
        String newPassword = passwordEncoder.encode(decryptPassword);
//        更新密码
        shopEmployeeService.updatePasswordByEmployeeId(employeeId, newPassword);
        tokenStore.deleteAllToken(SysTypeEnum.MULTISHOP.value().toString(),SecurityUtils.getShopUser().getUserId());
        return ServerResponseEntity.success();
    }
    @GetMapping("/info/{employeeId}" )
    @PreAuthorize("@pms.hasPermission('sys:shopEmployee:info')")
    @Operation(summary = "通过id查询用户信息" , description = "通过id查询用户信息")
    @Parameter(name = "employeeId", description = "系统用户id" )
    public ServerResponseEntity<ShopEmployee> getById(@PathVariable("employeeId") Long employeeId) {
        ShopEmployee dbShopEmployee = shopEmployeeService.getShopEmployeeById(employeeId);
        dbShopEmployee.setUserId(null);
        //获取用户所属的角色列表
        List<Long> roleIdList = shopRoleService.listRoleIdByEmployeeId(employeeId);
        dbShopEmployee.setRoleIdList(roleIdList);
        return ServerResponseEntity.success(dbShopEmployee);
    }
    /**
     * 获取用户信息
     */
    @GetMapping("/shopEmployeeInfo")
    @PreAuthorize("@pms.hasPermission('sys:shopEmployee:info')")
    @Operation(summary = "获取用户信息" , description = "获取用户信息")
    public ServerResponseEntity<ShopEmployee> shopEmployeeInfo(){
        ShopEmployee shopEmployee = shopEmployeeService.getShopEmployeeById(SecurityUtils.getShopUser().getEmployeeId());
        shopEmployee.setEmployeeId(null);
        shopEmployee.setPassword(null);
        return ServerResponseEntity.success(shopEmployee);
    }
    /**
     * 新增系统用户
     * @param shopEmployee 系统用户
     * @return 是否新增成功
     */
    @PostMapping
    @PreAuthorize("@pms.hasPermission('sys:shopEmployee:save')" )
    @Operation(summary = "新增用户信息" , description = "新增用户信息")
    public ServerResponseEntity<String> save(@RequestBody @Valid ShopEmployee shopEmployee) {
        shopEmployee.setShopId(SecurityUtils.getShopUser().getShopId());
        shopEmployee.setCreateEmployeeId(SecurityUtils.getShopUser().getEmployeeId());
        shopEmployee.setType(PositionType.STAFF.value());
        String decryptPassword = passwordManager.decryptPassword(shopEmployee.getPassword());
        shopEmployee.setPassword(passwordEncoder.encode(decryptPassword));
        shopEmployeeService.saveUserAndUserRole(shopEmployee);
        return ServerResponseEntity.success();
    }
    /**
     * 修改系统用户
     * @param shopEmployee 系统用户
     * @return 是否修改成功
     */
    @PutMapping
    @PreAuthorize("@pms.hasPermission('sys:shopEmployee:update')" )
    @Operation(summary = "修改用户信息" , description = "修改用户信息")
    public ServerResponseEntity<String> updateById(@RequestBody @Valid ShopEmployee shopEmployee) {
        if (Objects.isNull(shopEmployee.getEmployeeId())) {
            throw new YamiShopBindException("员工id不能为空");
        }
        Long employeeId = SecurityUtils.getShopUser().getEmployeeId();
        if(Objects.equals(shopEmployee.getEmployeeId().intValue(), Constant.SUPER_ADMIN_ID) && BooleanUtil.isFalse(permission)) {
            throw new YamiShopBindException("yami.no.auth");
        }
        String password = passwordManager.decryptPassword(shopEmployee.getPassword());
        ShopEmployee dbEmployee = shopEmployeeService.getShopEmployeeById(shopEmployee.getEmployeeId());
        //修改管理员账号但修改人不是管理员,则抛出异常(只有管理员可以改管理员信息)
        if (Objects.equals( PositionType.ADMIN.value(),dbEmployee.getType()) &&
            !Objects.equals(shopEmployee.getEmployeeId(), employeeId)) {
            // 您没有权限修改管理员信息
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.not.permission.modify.administrator.info"));
        }
        if (StrUtil.isBlank(password)) {
            shopEmployee.setPassword(null);
        } else {
            shopEmployee.setPassword(passwordEncoder.encode(password));
        }
        shopEmployeeService.updateUserAndUserRole(shopEmployee);
        // 禁用用户之后将该用户登录信息清除
        if (Objects.equals(shopEmployee.getStatus(), 0)) {
            tokenStore.deleteAllToken(SysTypeEnum.MULTISHOP.value().toString(), shopEmployee.getEmployeeId().toString());
        }
        return ServerResponseEntity.success();
    }
    /**
     * 通过id删除系统用户
     * @return 是否删除成功
     */
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('sys:shopEmployee:delete')" )
    @Operation(summary = "通过id删除用户信息" , description = "通过id删除用户信息")
    @Parameter(name = "employeeIds", description = "系统用户id列表" )
    public ServerResponseEntity<String> removeById(@RequestBody List<Long> employeeIds) {
        if (CollUtil.isEmpty(employeeIds)) {
            // 请选择需要删除的用户
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.select.user"));
        }
        // 获取该店铺的商家信息
        ShopEmployee admin = shopEmployeeService.getOne(Wrappers.lambdaQuery(ShopEmployee.class)
                .eq(ShopEmployee::getShopId, SecurityUtils.getShopUser().getShopId())
                .eq(ShopEmployee::getType, PositionType.ADMIN.value()));
        // 商家id
        Long adminId = admin.getEmployeeId();
        // 当前员工id
        Long currentEmployeeId = SecurityUtils.getShopUser().getEmployeeId();
        // 检查删除的员工中是否存在商家与当前员工
        for (Long id : employeeIds) {
            if (Objects.equals(id, adminId)) {
                throw new YamiShopBindException("yami.sys.admin.error");
            }
            if (Objects.equals(id, currentEmployeeId)) {
                throw new YamiShopBindException("yami.sys.delete.error");
            }
        }
        List<ShopEmployee> shopEmployees = shopEmployeeService.list(new LambdaQueryWrapper<ShopEmployee>().in(ShopEmployee::getEmployeeId, employeeIds));
        shopEmployeeService.removeEmployeesByIds(employeeIds);
        for (ShopEmployee shopEmployee : shopEmployees) {
            tokenStore.deleteAllToken(SysTypeEnum.MULTISHOP.value().toString(), shopEmployee.getEmployeeId().toString());
        }
        return ServerResponseEntity.success();
    }
    @GetMapping("/list")
    @Operation(summary = "获取店铺下的所有员工列表" , description = "获取店铺下的所有员工列表")
    public ServerResponseEntity<List<ShopEmployee>> list(@ParameterObject ShopEmployee shopEmployee) {
        shopEmployee.setShopId(SecurityUtils.getShopUser().getShopId());
        List<ShopEmployee> shopEmployeeList = shopEmployeeService.listByParam(shopEmployee);
        return ServerResponseEntity.success(shopEmployeeList);
    }
}
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/ShopMenuController.java
New file
@@ -0,0 +1,133 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.multishop.controller;
import cn.hutool.core.map.MapUtil;
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.security.multishop.model.YamiShopUser;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.sys.common.model.ShopMenu;
import com.yami.shop.sys.common.service.ShopMenuService;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * 菜单管理
 *
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@RestController
@AllArgsConstructor
@RequestMapping("/sys/shopMenu")
@Tag(name = "菜单管理接口")
public class ShopMenuController {
    private final ShopMenuService shopMenuService;
    /**
     * 分页查询
     *
     * @param page     分页对象
     * @param shopMenu 菜单管理
     * @return 分页数据
     */
    @GetMapping("/page")
    @Operation(summary = "分页获取菜单" , description = "分页获取菜单")
    public ServerResponseEntity<IPage<ShopMenu>> getShopMenuPage(PageParam<ShopMenu> page, @ParameterObject ShopMenu shopMenu) {
        return ServerResponseEntity.success(shopMenuService.page(page, new LambdaQueryWrapper<ShopMenu>()));
    }
    @GetMapping("/nav")
    @Operation(summary = "获取用户所拥有的菜单和权限" , description = "通过登陆用户的userId获取用户所拥有的菜单和权限")
    public ServerResponseEntity<Map<Object, Object>> nav(){
        List<ShopMenu> shopMenus = shopMenuService.listMenuByEmployeeId(SecurityUtils.getShopUser().getEmployeeId());
        //获取用户所以权限
        Set<String> authorities = SecurityUtils.getShopUser().getAuthorities();
        //获取已经隐藏的按钮权限信息
        Set<String> perms = shopMenuService.listConcealButtonPerms();
        //移除掉隐藏按钮的权限信息
        authorities.removeAll(perms);
        return ServerResponseEntity.success(MapUtil.builder().put("menuList", shopMenus).put("authorities", authorities).build());
    }
    /**
     * 获取菜单页面的表
     *
     * @return
     */
    @GetMapping("/table")
    @Operation(summary = "获取菜单页面的表" , description = "获取菜单页面的表")
    public ServerResponseEntity<List<ShopMenu>> table() {
        YamiShopUser shopUser = SecurityUtils.getShopUser();
        List<ShopMenu> shopMenus = shopMenuService.listMenuAndBtn(shopUser.getEmployeeId());
        return ServerResponseEntity.success(shopMenus);
    }
    /**
     * 所有菜单列表(用于新建、修改角色时 获取菜单的信息)
     */
    @GetMapping("/list")
    @Operation(summary = "获取用户所拥有的菜单(不包括按钮)" , description = "通过登陆用户的userId获取用户所拥有的菜单和权限")
    public ServerResponseEntity<List<ShopMenu>> list() {
        List<ShopMenu> shopMenus = shopMenuService.listSimpleMenuNoButton();
        return ServerResponseEntity.success(shopMenus);
    }
    /**
     * 选择菜单
     */
    @GetMapping("/listRootMenu")
    @Operation(summary = "选择菜单" , description = "选择菜单")
    public ServerResponseEntity<List<ShopMenu>> listRootMenu() {
        //查询列表数据
        List<ShopMenu> shopMenus = shopMenuService.listRootMenu();
        return ServerResponseEntity.success(shopMenus);
    }
    /**
     * 选择子菜单
     */
    @GetMapping("/listChildrenMenu")
    @Operation(summary = "选择子菜单" , description = "选择子菜单")
    public ServerResponseEntity<List<ShopMenu>> listChildrenMenu(Long parentId) {
        //查询列表数据
        List<ShopMenu> shopMenus = shopMenuService.listChildrenMenuByParentId(parentId);
        return ServerResponseEntity.success(shopMenus);
    }
    /**
     * 通过id查询菜单管理
     *
     * @param menuId id
     * @return 单个数据
     */
    @GetMapping("/info/{menuId}")
    @Operation(summary = "通过id查询菜单" , description = "通过id查询菜单")
    @Parameter(name = "menuId", description = "菜单id" )
    public ServerResponseEntity<ShopMenu> getById(@PathVariable("menuId") Long menuId) {
        return ServerResponseEntity.success(shopMenuService.getById(menuId));
    }
}
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/ShopRoleController.java
New file
@@ -0,0 +1,157 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.multishop.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.common.annotation.SysLog;
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.security.multishop.util.SecurityUtils;
import com.yami.shop.sys.common.model.ShopRole;
import com.yami.shop.sys.common.service.ShopMenuService;
import com.yami.shop.sys.common.service.ShopRoleService;
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.List;
import java.util.Objects;
/**
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@RestController
@RequestMapping("/sys/shopRole" )
@Tag(name = "权限角色接口")
public class ShopRoleController {
    @Autowired
    private ShopRoleService shopRoleService;
    @Autowired
    private ShopMenuService shopMenuService;
    /**
     * 分页查询
     * @param page 分页对象
     * @param shopRole 角色
     * @return 分页数据
     */
    @GetMapping("/page" )
    @PreAuthorize("@pms.hasPermission('sys:shopRole:page')")
    @Operation(summary = "分页获取角色" , description = "分页获取角色")
    public ServerResponseEntity<IPage<ShopRole>> getShopRolePage(PageParam<ShopRole> page, @ParameterObject ShopRole shopRole) {
        IPage<ShopRole> shopRoles = shopRoleService.page(page,new LambdaQueryWrapper<ShopRole>()
                .eq(ShopRole::getShopId,SecurityUtils.getShopUser().getShopId())
                .like(StrUtil.isNotBlank(shopRole.getRoleName()),ShopRole::getRoleName,shopRole.getRoleName())
                .orderByDesc(ShopRole::getCreateTime));
        return ServerResponseEntity.success(shopRoles);
    }
    /**
     * 角色列表
     */
    @GetMapping("/list")
    @PreAuthorize("@pms.hasPermission('sys:shopRole:list')")
    @Operation(summary = "获取角色列表" , description = "获取角色列表")
    public ServerResponseEntity<List<ShopRole>> list(){
        List<ShopRole> list = shopRoleService.list(new LambdaQueryWrapper<ShopRole>()
                .eq(ShopRole::getShopId,SecurityUtils.getShopUser().getShopId()));
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{roleId}" )
    @Operation(summary = "通过id查询角色" , description = "通过id查询角色")
    @Parameter(name = "roleId", description = "角色id" )
    public ServerResponseEntity<ShopRole> getById(@PathVariable("roleId") Long roleId) {
        ShopRole role = shopRoleService.getById(roleId);
        if (Objects.isNull(role)) {
            throw new YamiShopBindException("yami.shop.data.is.removed");
        }
        if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), role.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        //查询角色对应的菜单
        List<Long> menuList = shopMenuService.listMenuIdByRoleId(roleId);
        role.setMenuIdList(menuList);
        return ServerResponseEntity.success(role);
    }
    /**
     * 新增角色
     * @param shopRole 角色
     * @return 是否新增成功
     */
    @SysLog("新增角色" )
    @PostMapping
    @PreAuthorize("@pms.hasPermission('sys:shopRole:save')" )
    @Operation(summary = "新增角色" , description = "新增角色")
    public ServerResponseEntity<Boolean> save(@RequestBody ShopRole shopRole) {
        Long employeeId = SecurityUtils.getShopUser().getEmployeeId();
        Long shopId = SecurityUtils.getShopUser().getShopId();
        if (shopRoleService.count(new LambdaQueryWrapper<ShopRole>()
                .eq(ShopRole::getShopId,shopId)
                .eq(ShopRole::getRoleName, shopRole.getRoleName())) > 0) {
            // 系统已存在相同角色名称
            throw new YamiShopBindException("yami.sys.role.identical.name");
        }
        shopRole.setShopId(shopId);
        shopRole.setCreateEmployeeId(employeeId);
        Boolean isOk = shopRoleService.saveRoleAndRoleMenu(shopRole);
        return ServerResponseEntity.success(isOk);
    }
    /**
     * 修改角色
     * @param shopRole 角色
     * @return 是否修改成功
     */
    @SysLog("修改角色" )
    @PutMapping
    @PreAuthorize("@pms.hasPermission('sys:shopRole:update')" )
    @Operation(summary = "修改角色" , description = "修改角色")
    public ServerResponseEntity<Boolean> updateById(@RequestBody ShopRole shopRole) {
        int size = shopRoleService.count(new LambdaQueryWrapper<ShopRole>()
                .eq(ShopRole::getShopId, SecurityUtils.getShopUser().getShopId())
                .eq(ShopRole::getRoleName, shopRole.getRoleName())
                .ne(ShopRole::getRoleId, shopRole.getRoleId())
        );
        if (size > 0) {
            // 系统已存在相同角色名称
            throw new YamiShopBindException("yami.sys.role.identical.name");
        }
        Boolean update = shopRoleService.updateRoleAndRoleMenu(shopRole);
        return ServerResponseEntity.success(update);
    }
    /**
     * 通过id删除角色
     * @return 是否删除成功
     */
    @SysLog("删除角色" )
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('sys:shopRole:delete')" )
    @Operation(summary = "通过id删除角色" , description = "通过id删除角色")
    @Parameter(name = "roleIds", description = "角色id列表" )
    public ServerResponseEntity<Boolean> removeById(@RequestBody Long[] roleIds) {
        Boolean delete = shopRoleService.deleteBatch(roleIds);
        return ServerResponseEntity.success(delete);
    }
}
yami-shop-sys/yami-shop-sys-multishop/src/main/java/com/yami/shop/sys/multishop/controller/SysConfigController.java
New file
@@ -0,0 +1,42 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.multishop.controller;
import com.alibaba.fastjson.JSONObject;
import com.yami.shop.bean.vo.SysLangVo;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
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 yami
 */
@RestController
@Tag(name = "系统配置信息")
@RequestMapping("/sys/config")
public class SysConfigController {
    @Autowired
    private SysConfigService sysConfigService;
    @Operation(summary = "获取语言类型" , description = "获取语言类型")
    @GetMapping("/lang")
    public ServerResponseEntity<SysLangVo> getLang(){
        String str = sysConfigService.getValue("LANGUAGE_CONFIG");
        SysLangVo lang = JSONObject.parseObject(str, SysLangVo.class);
        return ServerResponseEntity.success(lang);
    }
}
yami-shop-sys/yami-shop-sys-platform/pom.xml
New file
@@ -0,0 +1,27 @@
<?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-sys</artifactId>
        <groupId>com.yami.shop</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-sys-platform</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-sys-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-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/adapter/PlatformSignAuthAdapter.java
New file
@@ -0,0 +1,83 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.adapter;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.common.config.Constant;
import com.yami.shop.security.common.adapter.SignAuthAdapter;
import com.yami.shop.security.common.bo.UserInfoInTokenBO;
import com.yami.shop.security.common.enums.SysTypeEnum;
import com.yami.shop.sys.common.dao.SysMenuMapper;
import com.yami.shop.sys.common.dao.SysUserMapper;
import com.yami.shop.sys.common.model.SysMenu;
import com.yami.shop.sys.common.model.SysUser;
import com.yami.shop.sys.common.service.SysUserService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
 *
 * @author lgh on 2018/09/07.
 */
@Service
@AllArgsConstructor
public class PlatformSignAuthAdapter implements SignAuthAdapter {
    private final SysUserService sysUserService;
    private final SysMenuMapper sysMenuMapper;
    private final SysUserMapper sysUserMapper;
    @Override
    public UserInfoInTokenBO loadUserInfoInToken(Map<String, Object> dataMap) {
        UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
        Long userId = (Long)dataMap.get("userId");
        SysUser sysUser;
        // 没有指定用户,默认为管理员
        if (Objects.isNull(userInfoInToken.getBizUserId())) {
            sysUser = sysUserService.getSysUserById((long) Constant.SUPER_ADMIN_ID);
        } else {
            sysUser = sysUserService.getSysUserById(userId);
        }
        userInfoInToken.setUserId(String.valueOf(userId));
        userInfoInToken.setSysType(SysTypeEnum.PLATFORM.value());
        userInfoInToken.setEnabled(sysUser.getStatus() == 1);
        userInfoInToken.setPerms(getUserPermissions(sysUser.getUserId()));
        userInfoInToken.setNikeName(sysUser.getNickName());
        return userInfoInToken;
    }
    private Set<String> getUserPermissions(Long userId) {
        List<String> permsList;
        //系统管理员,拥有最高权限
        if(userId == Constant.SUPER_ADMIN_ID){
            List<SysMenu> menuList = sysMenuMapper.selectList(Wrappers.emptyWrapper());
            permsList = menuList.stream().map(SysMenu::getPerms).collect(Collectors.toList());
        }else{
            permsList = sysUserMapper.queryAllPerms(userId);
            //去除隐藏按钮的用户权限
            permsList.removeAll(sysMenuMapper.listConcealButtonPerms());
        }
        return permsList.stream().flatMap((perms)->{
                    if (StrUtil.isBlank(perms)) {
                        return null;
                    }
                    return Arrays.stream(perms.trim().split(StrUtil.COMMA));
                }
        ).collect(Collectors.toSet());
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/aspect/SysLogAspect.java
New file
@@ -0,0 +1,91 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.aspect;
import cn.hutool.core.date.SystemClock;
import com.google.gson.Gson;
import com.yami.shop.common.util.IPHelper;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.sys.common.model.SysLog;
import com.yami.shop.sys.common.service.SysLogService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author lgh
 */
@Slf4j
@Aspect
@Component
@AllArgsConstructor
public class SysLogAspect {
    private final SysLogService sysLogService;
    private final Gson gson;
    @Around("@annotation(sysLog)")
    public Object around(ProceedingJoinPoint joinPoint, com.yami.shop.common.annotation.SysLog sysLog) throws Throwable {
        long beginTime = SystemClock.now();
        //执行方法
        Object result = joinPoint.proceed();
        //执行时长(毫秒)
        long time = SystemClock.now() - beginTime;
        SysLog sysLogEntity = new SysLog();
        if(sysLog != null){
            //注解上的描述
            sysLogEntity.setOperation(sysLog.value());
        }
        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        sysLogEntity.setMethod(className + "." + methodName + "()");
        sysLogEntity.setParams(null);
        //请求的参数
        Object[] args = joinPoint.getArgs();
        if(args != null && args.length > 0) {
            String params = null;
            if(Objects.equals(args[0].getClass().getName(), PageParam.class.getName())){
                PageParam<Object> pageParam = (PageParam<Object>) args[0];
                List<Object> records = pageParam.getRecords();
                params = gson.toJson(records);
            }else{
                params = gson.toJson(args);
            }
            sysLogEntity.setParams(params);
        }
        //设置IP地址
        sysLogEntity.setIp(IPHelper.getIpAddr());
        //用户名
        String username = SecurityUtils.getSysUser().getUsername();
        sysLogEntity.setUsername(username);
        sysLogEntity.setTime(time);
        sysLogEntity.setCreateDate(new Date());
        //保存系统日志
        sysLogService.save(sysLogEntity);
        return result;
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/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.sys.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("sysSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi sysRestApi() {
        return GroupedOpenApi.builder()
                .group("系统配置")
                .packagesToScan("com.yami.shop.sys.platform.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/ShopMenuController.java
New file
@@ -0,0 +1,208 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.controller;
import cn.hutool.core.util.BooleanUtil;
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.common.config.Constant;
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.PageParam;
import com.yami.shop.security.platform.model.YamiSysUser;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.sys.common.constant.MenuType;
import com.yami.shop.sys.common.model.ShopMenu;
import com.yami.shop.sys.common.service.ShopMenuService;
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.beans.factory.annotation.Value;
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;
import java.util.Set;
/**
 * 菜单管理
 *
 * @author yami
 * @date 2021-03-01 17:42:09
 */
@Tag(name = "菜单管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/sys/shopMenu")
public class ShopMenuController {
    private final ShopMenuService shopMenuService;
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    @GetMapping("/page")
    @Operation(summary = "分页查询" , description = "分页查询")
    public ServerResponseEntity<IPage<ShopMenu>> getShopMenuPage(PageParam<ShopMenu> page, @ParameterObject ShopMenu shopMenu) {
        return ServerResponseEntity.success(shopMenuService.page(page, new LambdaQueryWrapper<ShopMenu>()));
    }
    @GetMapping("/table")
    @Operation(summary = "获取菜单页面的表" , description = "获取菜单页面的表")
    public ServerResponseEntity<List<ShopMenu>> table() {
        YamiSysUser sysUser = SecurityUtils.getSysUser();
        List<ShopMenu> shopMenus = shopMenuService.listMenuAndBtn(sysUser.getUserId());
        return ServerResponseEntity.success(shopMenus);
    }
    /**
     * 所有菜单列表(用于新建、修改角色时 获取菜单的信息)
     */
    @GetMapping("/list")
    @Operation(summary = "获取用户所拥有的菜单(不包括按钮)" , description = "通过登陆用户的userId获取用户所拥有的菜单和权限")
    public ServerResponseEntity<List<ShopMenu>> list() {
        List<ShopMenu> shopMenus = shopMenuService.listSimpleMenuNoButton();
        return ServerResponseEntity.success(shopMenus);
    }
    @GetMapping("/listRootMenu")
    @Operation(summary = "获取菜单列表" , description = "获取菜单列表")
    public ServerResponseEntity<List<ShopMenu>> listRootMenu() {
        //查询列表数据
        List<ShopMenu> shopMenus = shopMenuService.listRootMenu();
        return ServerResponseEntity.success(shopMenus);
    }
    @GetMapping("/listChildrenMenu")
    @Operation(summary = "获取子菜单列表" , description = "获取子菜单列表")
    @Parameter(name = "parentId", description = "上级菜单id" )
    public ServerResponseEntity<List<ShopMenu>> listChildrenMenu(Long parentId) {
        //查询列表数据
        List<ShopMenu> shopMenus = shopMenuService.listChildrenMenuByParentId(parentId);
        return ServerResponseEntity.success(shopMenus);
    }
    @GetMapping("/info/{menuId}")
    @Operation(summary = "查询菜单管理" , description = "通过id查询菜单管理")
    @Parameter(name = "menuId", description = "菜单id" )
    public ServerResponseEntity<ShopMenu> getById(@PathVariable("menuId") Long menuId) {
        return ServerResponseEntity.success(shopMenuService.getById(menuId));
    }
    @PostMapping
    @Operation(summary = "新增菜单信息" , description = "新增菜单信息")
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid ShopMenu shopMenu) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.fail(ResponseEnum.NOT_FOUND);
        }
        //数据校验
        verifyForm(shopMenu);
        return ServerResponseEntity.success(shopMenuService.save(shopMenu));
    }
    @PutMapping
    @Operation(summary = "修改菜单信息" , description = "修改菜单信息")
    public ServerResponseEntity<String> updateById(@RequestBody @Valid ShopMenu shopMenu) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.fail(ResponseEnum.NOT_FOUND);
        }
        //数据校验
        verifyForm(shopMenu);
        if (shopMenu.getType() == MenuType.MENU.getValue() && StrUtil.isBlank(shopMenu.getUrl())) {
            // 菜单URL不能为空
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.menu.exist"));
        }
        boolean isOk = shopMenuService.updateById(shopMenu);
        //修改子菜单按钮显示隐藏状态
        Set<String> perms = shopMenuService.updateSonMenuState(shopMenu.getMenuId(), shopMenu.getHidden());
        //获取用户的所以菜单权限信息
        Set<String> authorities = SecurityUtils.getSysUser().getAuthorities();
        //隐藏就移除用户对应按钮的权限信息,显示就添加
        if (shopMenu.getHidden() == 1){
            //移除
            authorities.removeAll(perms);
        }else {
            //添加
            authorities.addAll(perms);
        }
        return ServerResponseEntity.success(String.valueOf(isOk));
    }
    @DeleteMapping("/{menuId}")
    @Operation(summary = "删除菜单管理" , description = "通过id删除菜单管理")
    @Parameter(name = "menuId", description = "菜单id" )
    public ServerResponseEntity<String> removeById(@PathVariable Long menuId) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.fail(ResponseEnum.NOT_FOUND);
        }
        if(menuId <= Constant.SYS_MENU_MAX_ID){
            // 系统菜单,不能删除
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.menu.delete.error"));
        }
        //判断是否有子菜单或按钮
        List<ShopMenu> shopMenus = shopMenuService.listChildrenMenuByParentId(menuId);
        if(shopMenus.size() > 0){
            // 请先删除子菜单或按钮
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.menu.child.delete"));
        }
        shopMenuService.deleteMenuAndRoleMenu(menuId);
        return ServerResponseEntity.success();
    }
    /**
     * 验证参数是否正确
     */
    private void verifyForm(ShopMenu shopMenu) {
        if (Objects.equals(shopMenu.getMenuId(), shopMenu.getParentId())) {
            // 自己不能是自己的上级
            throw new YamiShopBindException("yami.sys.menu.user.error");
        }
        if (shopMenu.getType() == MenuType.MENU.getValue()) {
            if (StrUtil.isBlank(shopMenu.getUrl())) {
                // 菜单URL不能为空
                throw new YamiShopBindException("yami.sys.menu.exist");
            }
        }
        //上级菜单类型
        int parentType = MenuType.CATALOG.getValue();
        if (shopMenu.getParentId() != 0) {
            ShopMenu parentMenu = shopMenuService.getById(shopMenu.getParentId());
            parentType = parentMenu.getType();
        }
        //目录、菜单
        if (shopMenu.getType() == MenuType.CATALOG.getValue() || shopMenu.getType() == MenuType.MENU.getValue()) {
            if (parentType != MenuType.CATALOG.getValue()) {
                // // 上级菜单不为空时,只能为菜单类型
                throw new YamiShopBindException("yami.sys.menu.superior.list");
            }
            return;
        }
        //按钮
        if (shopMenu.getType() == MenuType.BUTTON.getValue()) {
            if ((parentType != 0) && parentType != MenuType.MENU.getValue()) {
                // 上级菜单不为空时,只能为菜单类型
                throw new YamiShopBindException("yami.sys.menu.superior.menu");
            }
        }
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysAccessKeyController.java
New file
@@ -0,0 +1,125 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.model.SysAccessKey;
import com.yami.shop.common.annotation.SysLog;
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.service.SysAccessKeyService;
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.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Objects;
/**
 * 系统访问密钥
 *
 * @author YXF
 * @date 2021-10-19 14:41:38
 */
@Tag(name = "系统访问密钥")
@RestController
@AllArgsConstructor
@RequestMapping("/platform/sysAccessKey" )
public class SysAccessKeyController {
    private final SysAccessKeyService sysAccessKeyService;
    @GetMapping("/page" )
    @Operation(summary = "分页查询" , description = "分页查询")
    public ServerResponseEntity<IPage<SysAccessKey>> getSysKeyPage(PageParam<SysAccessKey> page, @ParameterObject SysAccessKey sysAccessKey) {
        PageParam<SysAccessKey> keyPage = sysAccessKeyService.page(page, new LambdaQueryWrapper<SysAccessKey>()
                .like(StrUtil.isNotBlank(sysAccessKey.getName()), SysAccessKey::getName, sysAccessKey.getName())
                .like(StrUtil.isNotBlank(sysAccessKey.getAccessId()), SysAccessKey::getAccessId, sysAccessKey.getAccessId())
        );
        if (CollUtil.isNotEmpty(keyPage.getRecords())) {
            for (SysAccessKey accessKey : keyPage.getRecords()) {
                accessKey.setAccessKey(null);
            }
        }
        return ServerResponseEntity.success(keyPage);
    }
    @GetMapping("/info/{sysAccessKeyId}" )
    @Operation(summary = "查询系统访问密钥" , description = "通过id查询系统访问密钥")
    @Parameter(name = "sysAccessKeyId", description = "系统访问密钥id" )
    public ServerResponseEntity<SysAccessKey> getById(@PathVariable("sysAccessKeyId") Long sysAccessKeyId) {
        SysAccessKey sysAccessKey = sysAccessKeyService.getBySysAccessKeyId(sysAccessKeyId);
        return ServerResponseEntity.success(sysAccessKey);
    }
    @SysLog("新增系统访问密钥" )
    @PostMapping
    @Operation(summary = "新增系统访问密钥" , description = "新增系统访问密钥")
    @PreAuthorize("@pms.hasPermission('platform:sysAccessKey:save')" )
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid SysAccessKey sysAccessKey) {
        sysAccessKeyService.saveSysAccessKey(sysAccessKey);
        return ServerResponseEntity.success();
    }
    @SysLog("更新系统访问密钥" )
    @PutMapping
    @Operation(summary = "更新系统访问密钥" , description = "更新系统访问密钥")
    @PreAuthorize("@pms.hasPermission('platform:sysAccessKey:update')" )
    public ServerResponseEntity<Boolean> update(@RequestBody @Valid SysAccessKey sysAccessKey) {
        SysAccessKey sysAccessKeyDb = sysAccessKeyService.getBySysAccessKeyId(sysAccessKey.getSysAccessKeyId());
        sysAccessKeyService.updateSysAccessKey(sysAccessKey);
        sysAccessKeyService.removeCacheById(sysAccessKeyDb.getAccessId());
        return ServerResponseEntity.success();
    }
    @SysLog("重置系统访问密钥" )
    @PutMapping("/resetAccessKey")
    @Operation(summary = "重置系统访问密钥" , description = "重置系统访问密钥")
    @Parameter(name = "sysAccessKeyId", description = "系统访问密钥id" )
    @PreAuthorize("@pms.hasPermission('platform:sysAccessKey:reset')" )
    public ServerResponseEntity<Boolean> resetAccessKey(@RequestBody Long sysAccessKeyId) {
        if (Objects.isNull(sysAccessKeyId)) {
            // sysAccessKeyId 不能为空
            throw new YamiShopBindException("yami.sys.access.key.id.not.null");
        }
        SysAccessKey sysAccessKeyDb = sysAccessKeyService.getBySysAccessKeyId(sysAccessKeyId);
        if (Objects.isNull(sysAccessKeyDb)) {
            return ServerResponseEntity.success();
        }
        sysAccessKeyService.resetAccessKey(sysAccessKeyId);
        sysAccessKeyService.removeCacheById(sysAccessKeyDb.getAccessId());
        return ServerResponseEntity.success();
    }
    @SysLog("删除系统访问密钥" )
    @DeleteMapping("/{sysAccessKeyId}" )
    @Operation(summary = "删除系统访问密钥" , description = "通过id删除系统访问密钥")
    @Parameter(name = "sysAccessKeyId", description = "系统访问密钥id" )
    @PreAuthorize("@pms.hasPermission('platform:sysAccessKey:delete')" )
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long sysAccessKeyId) {
        SysAccessKey sysAccessKeyDb = sysAccessKeyService.getBySysAccessKeyId(sysAccessKeyId);
        if (Objects.isNull(sysAccessKeyDb)) {
            return ServerResponseEntity.success();
        }
        sysAccessKeyService.removeById(sysAccessKeyId);
        sysAccessKeyService.removeCacheById(sysAccessKeyDb.getAccessId());
        return ServerResponseEntity.success();
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysConfigController.java
New file
@@ -0,0 +1,106 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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.common.annotation.SysLog;
import com.yami.shop.common.bean.SysConfig;
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.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.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Objects;
/**
 * 系统配置信息
 * @author lgh
 */
@Tag(name = "系统配置信息")
@ConditionalOnProperty(prefix = "yami", name = "expose.permission", havingValue = "true", matchIfMissing = true)
@RestController
@RequestMapping("/sys/config")
public class SysConfigController{
    @Autowired
    private SysConfigService sysConfigService;
    @GetMapping("/page")
    @Operation(summary = "所有配置列表" , description = "所有配置列表")
    @Parameter(name = "paramKey", description = "参数名" )
    @PreAuthorize("@pms.hasPermission('sys:config:page')")
    public ServerResponseEntity<IPage<SysConfig>> page(String paramKey,PageParam<SysConfig> page){
        IPage<SysConfig> sysConfigs = sysConfigService.page(page, new LambdaQueryWrapper<SysConfig>().like(StrUtil.isNotBlank(paramKey),SysConfig::getParamKey,paramKey));
        return ServerResponseEntity.success(sysConfigs);
    }
    @GetMapping("/info/{id}")
    @Operation(summary = "配置信息" , description = "配置信息")
    @Parameter(name = "id", description = "配置id" )
    @PreAuthorize("@pms.hasPermission('sys:config:info')")
    public ServerResponseEntity<SysConfig> info(@PathVariable("id") Long id){
        SysConfig config = sysConfigService.getById(id);
        return ServerResponseEntity.success(config);
    }
    @SysLog("保存配置")
    @PostMapping
    @Operation(summary = "保存配置" , description = "保存配置")
    @PreAuthorize("@pms.hasPermission('sys:config:save')")
    public ServerResponseEntity<Void> save(@RequestBody @Valid SysConfig config){
        if (sysConfigService.count(new LambdaQueryWrapper<SysConfig>()
                .eq(SysConfig::getParamKey, config.getParamKey())) > 0) {
            // 系统已存在相同配置的key
            throw new YamiShopBindException("yami.same.key");
        }
        sysConfigService.save(config);
        return ServerResponseEntity.success();
    }
    @SysLog("修改配置")
    @PutMapping
    @Operation(summary = "修改配置" , description = "修改配置")
    @PreAuthorize("@pms.hasPermission('sys:config:update')")
    public ServerResponseEntity<Void> update(@RequestBody @Valid SysConfig config){
        SysConfig dbSysConfig = sysConfigService.getOne(new LambdaQueryWrapper<SysConfig>()
                .eq(SysConfig::getParamKey, config.getParamKey()));
        if (dbSysConfig != null && !Objects.equals(dbSysConfig.getParamKey(),config.getParamKey())) {
            // 系统已存在相同配置的key
            throw new YamiShopBindException("yami.same.key");
        }
        sysConfigService.updateById(config);
        return ServerResponseEntity.success();
    }
    @SysLog("删除配置")
    @DeleteMapping
    @Operation(summary = "删除配置" , description = "删除配置")
    @Parameter(name = "configIds", description = "配置id列表" )
    @PreAuthorize("@pms.hasPermission('sys:config:delete')")
    public ServerResponseEntity<Void> delete(@RequestBody Long[] configIds){
        sysConfigService.deleteBatch(configIds);
        return ServerResponseEntity.success();
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysLogController.java
New file
@@ -0,0 +1,57 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.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.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.sys.common.model.SysLog;
import com.yami.shop.sys.common.service.SysLogService;
import io.swagger.v3.oas.annotations.tags.Tag;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * 系统日志
 * @author lgh
 */
@Tag(name = "系统日志")
@RestController
@RequestMapping("/sys/log")
public class SysLogController {
    @Autowired
    private SysLogService sysLogService;
    @GetMapping("/page")
    @Operation(summary = "列表" , description = "列表")
    @PreAuthorize("@pms.hasPermission('sys:log:page')")
    public ServerResponseEntity<IPage<SysLog>> page(@ParameterObject SysLog sysLog, PageParam<SysLog> page){
        IPage<SysLog> sysLogs = sysLogService.page(page,
                new LambdaQueryWrapper<SysLog>()
                        .like(StrUtil.isNotBlank(sysLog.getUsername()),SysLog::getUsername, sysLog.getUsername())
                        .like(StrUtil.isNotBlank(sysLog.getOperation()), SysLog::getOperation,sysLog.getOperation())
                        .orderByDesc(SysLog::getId)
        );
        return ServerResponseEntity.success(sysLogs);
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysMenuController.java
New file
@@ -0,0 +1,224 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.controller;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.yami.shop.common.annotation.SysLog;
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.ResponseEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.platform.model.YamiSysUser;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.sys.common.constant.MenuType;
import com.yami.shop.sys.common.model.SysMenu;
import com.yami.shop.sys.common.service.SysMenuService;
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.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
 * 系统菜单
 *
 * @author lgh
 */
@Tag(name = "系统菜单")
@RestController
@RequestMapping("/sys/menu")
@RequiredArgsConstructor
public class SysMenuController {
    private final SysMenuService sysMenuService;
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    @GetMapping("/nav")
    @Operation(summary = "获取用户所拥有的菜单和权限" , description = "通过登陆用户的userId获取用户所拥有的菜单和权限")
    public ServerResponseEntity<Map<Object, Object>> nav() {
        List<SysMenu> menuList = sysMenuService.listMenuByUserId(SecurityUtils.getSysUser().getUserId());
        //移除用户隐藏掉的按钮权限
        Set<String> authorities = SecurityUtils.getSysUser().getAuthorities();
        authorities.removeAll(
                sysMenuService.listConcealButtonPerms());
        return ServerResponseEntity.success(MapUtil.builder().put("menuList", menuList).put("authorities",  authorities).build());
    }
    @GetMapping("/table")
    @Operation(summary = "获取菜单页面的表" , description = "获取菜单页面的表")
    public ServerResponseEntity<List<SysMenu>> table() {
        YamiSysUser sysUser = SecurityUtils.getSysUser();
        List<SysMenu> sysMenuList = sysMenuService.listMenuAndBtn(sysUser.getUserId());
        return ServerResponseEntity.success(sysMenuList);
    }
    /**
     * 所有菜单列表(用于新建、修改角色时 获取菜单的信息)
     */
    @GetMapping("/list")
    @Operation(summary = "获取用户所拥有的菜单(不包括按钮)" , description = "通过登陆用户的userId获取用户所拥有的菜单和权限")
    public ServerResponseEntity<List<SysMenu>> list() {
        List<SysMenu> sysMenuList = sysMenuService.listSimpleMenuNoButton();
        return ServerResponseEntity.success(sysMenuList);
    }
    @GetMapping("/listRootMenu")
    @Operation(summary = "选择菜单" , description = "选择菜单")
    public ServerResponseEntity<List<SysMenu>> listRootMenu() {
        //查询列表数据
        List<SysMenu> menuList = sysMenuService.listRootMenu();
        return ServerResponseEntity.success(menuList);
    }
    @GetMapping("/listChildrenMenu")
    @Operation(summary = "选择子菜单" , description = "选择子菜单")
    @Parameter(name = "parentId", description = "父菜单id" )
    public ServerResponseEntity<List<SysMenu>> listChildrenMenu(Long parentId) {
        //查询列表数据
        List<SysMenu> menuList = sysMenuService.listChildrenMenuByParentId(parentId);
        return ServerResponseEntity.success(menuList);
    }
    @GetMapping("/info/{menuId}")
    @Operation(summary = "菜单信息" , description = "菜单信息")
    @Parameter(name = "menuId", description = "菜单id" )
    @PreAuthorize("@pms.hasPermission('sys:menu:info')")
    public ServerResponseEntity<SysMenu> info(@PathVariable("menuId") Long menuId) {
        SysMenu menu = sysMenuService.getById(menuId);
        return ServerResponseEntity.success(menu);
    }
    @SysLog("保存菜单")
    @PostMapping
    @Operation(summary = "保存菜单" , description = "保存菜单")
    @PreAuthorize("@pms.hasPermission('sys:menu:save')")
    public ServerResponseEntity<Void> save(@Valid @RequestBody SysMenu menu) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.fail(ResponseEnum.NOT_FOUND);
        }
        //数据校验
        verifyForm(menu);
        sysMenuService.save(menu);
        return ServerResponseEntity.success();
    }
    @SysLog("修改菜单")
    @PutMapping
    @Operation(summary = "修改菜单" , description = "修改菜单")
    @PreAuthorize("@pms.hasPermission('sys:menu:update')")
    public ServerResponseEntity<String> update(@Valid @RequestBody SysMenu menu) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.fail(ResponseEnum.NOT_FOUND);
        }
        //数据校验
        verifyForm(menu);
        if (menu.getType() == MenuType.MENU.getValue()) {
            if (StrUtil.isBlank(menu.getUrl())) {
                // 菜单URL不能为空
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.menu.exist"));
            }
        }
        sysMenuService.updateById(menu);
        //修改子菜单按钮的显示隐藏状态
        Set<String> perms = sysMenuService.updateSonMenuState(menu.getMenuId(), menu.getHidden());
        Set<String> authorities = SecurityUtils.getSysUser().getAuthorities();
        if (menu.getHidden() == 1){
            boolean b = authorities.removeAll(perms);
        }else {
            boolean b = authorities.addAll(perms);
        }
        return ServerResponseEntity.success();
    }
    @SysLog("删除菜单")
    @DeleteMapping("/{menuId}")
    @Operation(summary = "删除" , description = "删除")
    @Parameter(name = "menuId", description = "菜单id" )
    @PreAuthorize("@pms.hasPermission('sys:menu:delete')")
    public ServerResponseEntity<String> delete(@PathVariable Long menuId) {
        if (BooleanUtil.isFalse(permission)) {
            return ServerResponseEntity.fail(ResponseEnum.NOT_FOUND);
        }
        if (menuId <= Constant.SYS_MENU_MAX_ID) {
            // 系统菜单,不能删除
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.menu.delete.error"));
        }
        //判断是否有子菜单或按钮
        List<SysMenu> menuList = sysMenuService.listChildrenMenuByParentId(menuId);
        if (menuList.size() > 0) {
            // 请先删除子菜单或按钮
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.menu.child.delete"));
        }
        sysMenuService.deleteMenuAndRoleMenu(menuId);
        return ServerResponseEntity.success();
    }
    /**
     * 验证参数是否正确
     */
    private void verifyForm(SysMenu menu) {
        if (menu.getType() == MenuType.MENU.getValue()) {
            if (StrUtil.isBlank(menu.getUrl())) {
                // 菜单URL不能为空
                throw new YamiShopBindException("yami.sys.menu.exist");
            }
        }
        if (Objects.equals(menu.getMenuId(), menu.getParentId())) {
            // 自己不能是自己的上级
            throw new YamiShopBindException("yami.sys.menu.user.error");
        }
        //上级菜单类型
        int parentType = MenuType.CATALOG.getValue();
        if (menu.getParentId() != 0) {
            SysMenu parentMenu = sysMenuService.getById(menu.getParentId());
            parentType = parentMenu.getType();
        }
        //目录、菜单
        if (menu.getType() == MenuType.CATALOG.getValue() ||
                menu.getType() == MenuType.MENU.getValue()) {
            if (parentType != MenuType.CATALOG.getValue()) {
                // 上级菜单只能为目录类型
                throw new YamiShopBindException("yami.sys.menu.superior.list");
            }
            return;
        }
        //按钮
        if (menu.getType() == MenuType.BUTTON.getValue()) {
            if ((parentType != 0) && parentType != MenuType.MENU.getValue()) {
                // 上级菜单不为空时,只能为菜单类型
                throw new YamiShopBindException("yami.sys.menu.superior.menu");
            }
        }
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysPconfigController.java
New file
@@ -0,0 +1,86 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.bean.SysConfig;
import com.yami.shop.common.response.ServerResponseEntity;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
 * @author chenlin
 * @DateTime: 2020/3/19 8:29
 * @description: 支付配置、文件上传配置、短信配置、快递配置、小程序配置、公众号配置
 */
@Tag(name = "系统配置")
@ConditionalOnProperty(prefix = "yami", name = "expose.permission", havingValue = "true", matchIfMissing = true)
@RestController
@RequestMapping("/sys/pconfig")
public class SysPconfigController {
    @Autowired
    private SysConfigService sysConfigService;
    @SysLog("获取配置信息")
    @GetMapping("/info/{key}")
    @Operation(summary = "获取配置信息" , description = "获取配置信息")
    @Parameter(name = "key", description = "参数名" )
    public ServerResponseEntity<String> info(@PathVariable("key")String key){
        return ServerResponseEntity.success(sysConfigService.getValue(key));
    }
    @SysLog("保存配置")
    @PostMapping("/save")
    @Operation(summary = "保存配置" , description = "保存配置")
    public ServerResponseEntity<Void> save(@RequestBody @Valid SysConfig sysConfig){
        String paramValue = sysConfig.getParamValue();
        String paramKey = sysConfig.getParamKey();
        int count = sysConfigService.count(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getParamKey,paramKey));
        if (count>0){
            sysConfigService.updateValueByKey(paramKey,paramValue);
        }else {
            sysConfigService.save(sysConfig);
        }
        sysConfigService.removeSysConfig(paramKey);
        return ServerResponseEntity.success();
    }
    @PostMapping("/saveDeliveryConfig")
    @Operation(summary = "保存物流查询配置信息" , description = "保存物流查询配置信息")
    public ServerResponseEntity<Void> saveDeliveryConfig(@RequestBody @Valid SysConfig sysConfig) {
        List<String> invalidKeys = sysConfigService.saveDeliveryConfig(sysConfig);
        invalidKeys.forEach(key -> {
            sysConfigService.removeSysConfig(key);
        });
        return ServerResponseEntity.success();
    }
    @PostMapping("/saveOssConfig")
    @Operation(summary = "保存文件上传配置信息" , description = "保存文件上传配置信息")
    public ServerResponseEntity<Void> saveOssConfig(@RequestBody @Valid SysConfig sysConfig) {
        List<String> invalidKeys = sysConfigService.saveOssConfig(sysConfig);
        invalidKeys.forEach(key -> {
            sysConfigService.removeSysConfig(key);
        });
        return ServerResponseEntity.success();
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysRoleController.java
New file
@@ -0,0 +1,125 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.annotation.SysLog;
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.sys.common.model.SysRole;
import com.yami.shop.sys.common.service.SysMenuService;
import com.yami.shop.sys.common.service.SysRoleService;
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.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * 角色管理
 * @author lgh
 */
@Tag(name = "角色管理")
@RestController
@RequestMapping("/sys/role")
public class SysRoleController{
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysMenuService sysMenuService;
    @GetMapping("/page")
    @Operation(summary = "分页查询" , description = "分页查询")
    @Parameter(name = "roleName", description = "角色名称" )
    @PreAuthorize("@pms.hasPermission('sys:role:page')")
    public ServerResponseEntity<IPage<SysRole>> page(String roleName, PageParam<SysRole> page){
        IPage<SysRole> sysRoles = sysRoleService.page(page,new LambdaQueryWrapper<SysRole>()
                .like(StrUtil.isNotBlank(roleName),SysRole::getRoleName,roleName)
                .orderByDesc(SysRole::getCreateTime));
        return ServerResponseEntity.success(sysRoles);
    }
    @GetMapping("/list")
    @Operation(summary = "角色列表" , description = "角色列表")
    @PreAuthorize("@pms.hasPermission('sys:role:list')")
    public ServerResponseEntity<List<SysRole>> list(){
        List<SysRole> list = sysRoleService.list();
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/info/{roleId}")
    @Operation(summary = "角色信息" , description = "角色信息")
    @Parameter(name = "roleId", description = "角色id" )
    @PreAuthorize("@pms.hasPermission('sys:role:info')")
    public ServerResponseEntity<SysRole> info(@PathVariable("roleId") Long roleId){
        SysRole role = sysRoleService.getById(roleId);
        //查询角色对应的菜单
        List<Long> menuList = sysMenuService.listMenuIdByRoleId(roleId);
        role.setMenuIdList(menuList);
        return ServerResponseEntity.success(role);
    }
    @SysLog("保存角色")
    @PostMapping
    @Operation(summary = "保存角色" , description = "保存角色")
    @PreAuthorize("@pms.hasPermission('sys:role:save')")
    public ServerResponseEntity<Void> save(@RequestBody SysRole role){
        if (sysRoleService.count(new LambdaQueryWrapper<SysRole>()
                .eq(SysRole::getRoleName, role.getRoleName())) > 0) {
            // 系统已存在相同角色名称
            throw new YamiShopBindException("yami.sys.role.identical.name");
        }
        sysRoleService.saveRoleAndRoleMenu(role);
        return ServerResponseEntity.success();
    }
    @SysLog("修改角色")
    @PutMapping
    @Operation(summary = "修改角色" , description = "修改角色")
    @PreAuthorize("@pms.hasPermission('sys:role:update')")
    public ServerResponseEntity<Void> update(@RequestBody SysRole role){
        int size = sysRoleService.count(new LambdaQueryWrapper<SysRole>()
                .eq(SysRole::getRoleName, role.getRoleName())
                .ne(SysRole::getRoleId, role.getRoleId())
        );
        if (size > 0) {
            // 系统已存在相同角色名称
            throw new YamiShopBindException("yami.sys.role.identical.name");
        }
        sysRoleService.updateRoleAndRoleMenu(role);
        return ServerResponseEntity.success();
    }
    @SysLog("删除角色")
    @DeleteMapping
    @Operation(summary = "删除角色" , description = "删除角色")
    @Parameter(name = "roleIds", description = "角色id" )
    @PreAuthorize("@pms.hasPermission('sys:role:delete')")
    public ServerResponseEntity<String> delete(@RequestBody Long[] roleIds){
        List<Long> ids = CollUtil.newArrayList(roleIds);
        sysRoleService.deleteBatch(ids);
        return ServerResponseEntity.success();
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysUpgradeInfoController.java
New file
@@ -0,0 +1,122 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.bean.SysUpgradeInfo;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.DateUtils;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.service.SysUpgradeInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
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 yami
 */
@RestController
@Tag(name = "系统升级信息")
@RequestMapping("/sys/upgrade")
public class SysUpgradeInfoController {
    @Autowired
    private SysUpgradeInfoService sysUpgradeInfoService;
    /**
     * 分页查询
     * @param page 分页对象
     * @param info
     * @return 分页数据
     */
    @GetMapping("/page" )
    @Operation(summary = "分页查询" , description = "分页查询")
    public ServerResponseEntity<IPage<SysUpgradeInfo>> getPurchaseProdPage(PageParam<SysUpgradeInfo> page, @ParameterObject SysUpgradeInfo info) {
        return ServerResponseEntity.success(sysUpgradeInfoService.page(page,
                new LambdaQueryWrapper<SysUpgradeInfo>().eq(SysUpgradeInfo::getId, info.getId())
                        .eq(SysUpgradeInfo::getEditionForce, info.getEditionForce())
                        .eq(SysUpgradeInfo::getPackageType, info.getPackageType())
                        .eq(SysUpgradeInfo::getEditionIssue, info.getEditionIssue())
                        .eq(SysUpgradeInfo::getEditionSilence, info.getEditionSilence())
                        .orderByDesc(SysUpgradeInfo::getCreateTime)
        ));
    }
    @GetMapping("/getReleaseInfo" )
    @Operation(summary = "查询最新升级公告" , description = "查询最新升级公告")
    public ServerResponseEntity<SysUpgradeInfo> getReleaseInfo() {
        List<SysUpgradeInfo>  sysUpgradeInfos= sysUpgradeInfoService.list(
                new LambdaQueryWrapper<SysUpgradeInfo>().orderByDesc(SysUpgradeInfo::getReleaseTime)
        );
        return ServerResponseEntity.success(sysUpgradeInfos.get(0));
    }
    /**
     * 通过id查询
     * @param  id
     * @return 单个数据
     */
    @GetMapping("/info/{id}" )
    @Operation(summary = "通过id查询" , description = "通过id查询")
    public ServerResponseEntity<SysUpgradeInfo> getById(@PathVariable("id") Long id) {
        return ServerResponseEntity.success(sysUpgradeInfoService.getById(id));
    }
    /**
     * 新增
     * @param info
     * @return 是否新增成功
     */
    @SysLog("新增" )
    @PostMapping("saveUpgradeInfo")
    @Operation(summary = "新增" , description = "新增")
    public ServerResponseEntity<Boolean> saveUpgradeInfo(@RequestBody @Valid SysUpgradeInfo info) {
        info.setCreateTime(DateUtils.dateToString(new Date()));
        info.setReleaseTime(DateUtils.dateToString(new Date()));
        return ServerResponseEntity.success(sysUpgradeInfoService.save(info));
    }
    /**
     * 修改
     * @param info
     * @return 是否修改成功
     */
    @SysLog("修改" )
    @PostMapping("updateUpgradeInfo")
    @Operation(summary = "修改" , description = "修改")
    public ServerResponseEntity<Boolean> updateUpgradeInfo(@RequestBody @Valid SysUpgradeInfo info) {
        info.setUpdateTime(DateUtils.dateToString(new Date()));
        return ServerResponseEntity.success(sysUpgradeInfoService.updateById(info));
    }
    /**
     * 通过id删除
     * @param  id
     * @return 是否删除成功
     */
    @SysLog("删除" )
    @DeleteMapping("delete/{id}" )
    @PreAuthorize("@pms.hasPermission('api:agent:delete')" )
    @Operation(summary = "通过id删除" , description = "通过id删除")
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long id) {
        return ServerResponseEntity.success(sysUpgradeInfoService.removeById(id));
    }
}
yami-shop-sys/yami-shop-sys-platform/src/main/java/com/yami/shop/sys/platform/controller/SysUserController.java
New file
@@ -0,0 +1,231 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.sys.platform.controller;
import cn.hutool.core.util.ArrayUtil;
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.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.config.Constant;
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.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.common.bo.UserInfoInTokenBO;
import com.yami.shop.security.common.enums.SysTypeEnum;
import com.yami.shop.security.common.manager.PasswordManager;
import com.yami.shop.security.common.manager.TokenStore;
import com.yami.shop.security.common.model.UpdatePasswordDto;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.sys.common.model.ShopEmployee;
import com.yami.shop.sys.common.model.SysUser;
import com.yami.shop.sys.common.service.SysRoleService;
import com.yami.shop.sys.common.service.SysUserService;
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.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
 * 系统用户
 * @author lgh
 */
@Tag(name = "系统用户")
@RestController
@RequestMapping("/sys/user")
@RequiredArgsConstructor
public class SysUserController {
    @Value("${yami.expose.operation.auth:}")
    private Boolean permission;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private PasswordManager passwordManager;
    @GetMapping("/page")
    @Operation(summary = "分页查询" , description = "分页查询")
    @Parameters(value = {
            @Parameter(name = "username", description = "用户名" ),
            @Parameter(name = "nickName", description = "用户昵称" )
    })
    @PreAuthorize("@pms.hasPermission('sys:user:page')")
    public ServerResponseEntity<IPage<SysUser>> page(String username, String nickName, PageParam<SysUser> page){
        IPage<SysUser> sysUserPage = sysUserService.page(page, new LambdaQueryWrapper<SysUser>()
                .like(StrUtil.isNotBlank(username), SysUser::getUsername, username)
                .like(StrUtil.isNotBlank(nickName), SysUser::getNickName, nickName));
        if (BooleanUtil.isFalse(permission)) {
            for (SysUser record : sysUserPage.getRecords()) {
                record.setMobile(PhoneUtil.hideBetween(record.getMobile()).toString());
            }
        }
        return ServerResponseEntity.success(sysUserPage);
    }
    @GetMapping("/info")
    @Operation(summary = "获取登录的用户信息" , description = "获取登录的用户信息")
    public ServerResponseEntity<SysUser> info(){
        return ServerResponseEntity.success(sysUserService.getSysUserById(SecurityUtils.getSysUser().getUserId()));
    }
    @SysLog("修改密码")
    @PostMapping("/password")
    @Operation(summary = "修改密码" , description = "修改当前登陆用户的密码")
    public ServerResponseEntity<String> password(@RequestBody @Valid UpdatePasswordDto param) {
        Long userId = SecurityUtils.getSysUser().getUserId();
        if (Objects.equals(userId.intValue(), Constant.SUPER_ADMIN_ID) && BooleanUtil.isFalse(permission)) {
            throw new YamiShopBindException("yami.no.auth");
        }
        SysUser dbUser = sysUserService.getSysUserById(userId);
        String password = passwordManager.decryptPassword(param.getPassword());
        if (!passwordEncoder.matches(password, dbUser.getPassword())) {
            // 原密码不正确
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.password.error"));
        }
        //新密码
        String decryptPassword = passwordManager.decryptPassword(param.getNewPassword());
        String newPassword = passwordEncoder.encode(decryptPassword);
//        更新密码
        sysUserService.updatePasswordByUserId(userId, newPassword);
        tokenStore.deleteAllToken(SysTypeEnum.PLATFORM.value().toString(),userId.toString());
        return ServerResponseEntity.success();
    }
    @GetMapping("/info/{userId}")
    @Operation(summary = "用户信息" , description = "用户信息")
    @Parameter(name = "userId", description = "用户id" )
    @PreAuthorize("@pms.hasPermission('sys:user:info')")
    public ServerResponseEntity<SysUser> info(@PathVariable("userId") Long userId){
        SysUser user = sysUserService.getSysUserById(userId);
        if (BooleanUtil.isFalse(permission)){
            user.setMobile(PhoneUtil.hideBetween(user.getMobile()).toString());
        }
        if (Objects.equals(userId, SecurityUtils.getSysUser().getUserId())) {
            user.setIsSelf(1);
        }
        user.setUserId(null);
        //获取用户所属的角色列表
        List<Long> roleIdList = sysRoleService.listRoleIdByUserId(userId);
        user.setRoleIdList(roleIdList);
        return ServerResponseEntity.success(user);
    }
    @GetMapping("/sysUserInfo")
    @Operation(summary = "获取用户信息" , description = "获取用户信息")
    @PreAuthorize("@pms.hasPermission('sys:user:info')")
    public ServerResponseEntity<SysUser> sysUserInfo(){
        SysUser user = sysUserService.getSysUserById(SecurityUtils.getSysUser().getUserId());
        user.setUserId(null);
        user.setPassword(null);
        return ServerResponseEntity.success(user);
    }
    @SysLog("保存用户")
    @PostMapping
    @Operation(summary = "保存用户" , description = "保存用户")
    @PreAuthorize("@pms.hasPermission('sys:user:save')")
    public ServerResponseEntity<String> save(@Valid @RequestBody SysUser user){
        String username = user.getUsername();
        SysUser dbUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, username));
        if (dbUser!=null) {
            // 该用户已存在
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.user.already"));
        }
        String decryptPassword = passwordManager.decryptPassword(user.getPassword());
        user.setPassword(passwordEncoder.encode(decryptPassword));
        sysUserService.saveUserAndUserRole(user);
        return ServerResponseEntity.success();
    }
    @SysLog("修改用户")
    @PutMapping
    @Operation(summary = "修改用户" , description = "修改用户")
    @PreAuthorize("@pms.hasPermission('sys:user:update')")
    public ServerResponseEntity<String> update(@Valid @RequestBody SysUser user){
        if (Objects.equals(user.getUserId().intValue(), Constant.SUPER_ADMIN_ID) && BooleanUtil.isFalse(permission)) {
            throw new YamiShopBindException("yami.no.auth");
        }
        String password = passwordManager.decryptPassword(user.getPassword());
        SysUser dbUserNameInfo = sysUserService.getByUserName(user.getUsername());
        //修改管理员账号但修改人不是管理员,则抛出异常(只有管理员可以改管理员信息)
        if (user.getUserId() == Constant.SUPER_ADMIN_ID &&
                SecurityUtils.getSysUser().getUserId() != Constant.SUPER_ADMIN_ID) {
            // 您没有权限修改管理员信息
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.not.permission.modify.administrator.info"));
        }
        if (dbUserNameInfo != null && !Objects.equals(dbUserNameInfo.getUserId(),user.getUserId())) {
            // 该用户已存在
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.user.already"));
        }
        if (StrUtil.isBlank(password)) {
            user.setPassword(null);
        }else {
            user.setPassword(passwordEncoder.encode(password));
        }
        sysUserService.updateUserAndUserRole(user);
        if (Objects.equals(user.getStatus(), StatusEnum.DISABLE.value())) {
            tokenStore.deleteAllToken(SysTypeEnum.PLATFORM.value().toString(), user.getUserId().toString());
        }
        return ServerResponseEntity.success();
    }
    @SysLog("删除用户")
    @DeleteMapping
    @Operation(summary = "删除用户" , description = "删除用户")
    @Parameter(name = "userIds", description = "用户id列表" )
    @PreAuthorize("@pms.hasPermission('sys:user:delete')")
    public ServerResponseEntity<String> delete(@RequestBody Long[] userIds){
        if (userIds.length == 0) {
            // 请选择需要删除的用户
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.select.user"));
        }
        if(ArrayUtil.contains(userIds, Constant.SUPER_ADMIN_ID)){
            // 系统管理员不能删除
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.admin.error"));
        }
        if(ArrayUtil.contains(userIds, SecurityUtils.getSysUser().getUserId())){
            // 当前用户不能删除
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.sys.delete.error"));
        }
        sysUserService.removeByIds(Arrays.asList(userIds));
        return ServerResponseEntity.success();
    }
}
yami-shop-task/pom.xml
New file
@@ -0,0 +1,43 @@
<?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>
    <description>任务大厅模块</description>
    <artifactId>yami-shop-task</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>yami-shop-task-api</module>
        <module>yami-shop-task-common</module>
    </modules>
    <dependencies>
        <!-- zxing生成二维码 -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>net.glxn</groupId>
            <artifactId>qrgen</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
</project>
yami-shop-task/yami-shop-task-api/pom.xml
New file
@@ -0,0 +1,39 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-task</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-task-api</artifactId>
    <dependencies>
        <!-- zxing生成二维码 -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>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-task-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
    </dependencies>
</project>
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/config/QRConfig.java
New file
@@ -0,0 +1,27 @@
package com.yami.shop.task.api.config;
import cn.hutool.extra.qrcode.QrConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.awt.*;
@Configuration
public class QRConfig {
    //采用JavaConfig的方式显示注入hutool中 生成二维码
    @Bean
    public QrConfig qrConfig(){
        //初始宽度和高度
        QrConfig qrConfig=new QrConfig(300,300);
        //设置边距,即二维码和边框的距离
        qrConfig.setMargin(2);
        //设置前景色
        qrConfig.setForeColor(Color.BLACK.getRGB());
        //设置背景色
        qrConfig.setBackColor(Color.WHITE.getRGB());
        return qrConfig;
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,35 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.task.api.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 任务大厅的swagger文档
 */
@Configuration("taskSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi taskRestApi() {
        return GroupedOpenApi.builder()
                .group("任务大厅接口")
                .packagesToScan("com.yami.shop.task.api.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/config/Zxing.java
New file
@@ -0,0 +1,59 @@
package com.yami.shop.task.api.config;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.UUID;
public class Zxing {
    public static void main(String[] args) {
        Zxing zxing = new Zxing();
        String QRCodeName = UUID.randomUUID().toString().replace("-", "").substring(0,7)+ ".png";
        String localImagePath = "C://" + QRCodeName;
        // 传参:二维码内容和生成路径
        if (zxing.orCode("https://www.baidu.com", localImagePath)) {
            System.out.println("ok,成功");
        } else {
            System.out.println("no,失败");
        }
    }
    public static boolean orCode(String content, String path) {
        /*
         * 图片的宽度和高度
         */
        int width = 300;
        int height = 300;
        // 图片的格式
        String format = "png";
        // 定义二维码的参数
        HashMap<EncodeHintType, Object> hints = new HashMap<>();
        // 定义字符集编码格式
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        // 纠错的等级 L > M > Q > H 纠错的能力越高可存储的越少,一般使用M
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        // 设置图片边距
        hints.put(EncodeHintType.MARGIN, 2);
        try {
            // 最终生成 参数列表 (1.内容 2.格式 3.宽度 4.高度 5.二维码参数)
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            // 写入到本地
            Path file = new File(path).toPath();
            MatrixToImageWriter.writeToPath(bitMatrix, format, file);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/PTaskAppController.java
New file
@@ -0,0 +1,56 @@
package com.yami.shop.task.api.controller;
import cn.hutool.crypto.digest.DigestUtil;
import com.yami.shop.bean.dto.TaskAppDto;
import com.yami.shop.bean.dto.TaskAppReleaseDto;
import com.yami.shop.common.response.R;
import com.yami.shop.security.api.util.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/p/taskApp")
@Tag(name = "任务app相关")
public class PTaskAppController {
    @GetMapping("/getAppSecret")
    @Operation(summary = "获取应用密钥")
    public R<?> getAppSecret(@Valid TaskAppDto taskAppDto) {
        String userId = SecurityUtils.getUser().getUserId();
        taskAppDto.setUserId(userId);
        String appSecret = "76cbf181d9d34650bf494a695cd04f53";
        taskAppDto.setAppSecret(appSecret);
        String appBagName = "com.my1618.app";
        taskAppDto.setAppBagName(appBagName);
        String data = taskAppDto.getAppBagName() + "-" + taskAppDto.getUserId() + "-" + taskAppDto.getAppId() + "-" + taskAppDto.getAppSecret();
        String hex = DigestUtil.sha256Hex(data);
        Map<String, Object> result = new HashMap<>();
        result.put("sign", hex);
        result.put("userId", taskAppDto.getUserId());
        result.put("appId", taskAppDto.getAppId());
        return R.success(result);
    }
    @GetMapping("/release")
    @Operation(summary = "app流量释放")
    public String getAppSecret( TaskAppReleaseDto taskAppReleaseDto) {
        String flag = "fail";
        flag = "success";
        return flag;
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/QrCodeController.java
New file
@@ -0,0 +1,92 @@
package com.yami.shop.task.api.controller;
import cn.hutool.core.util.IdUtil;
import com.google.gson.Gson;
import com.yami.shop.common.bean.AliOss;
import com.yami.shop.common.bean.Domain;
import com.yami.shop.common.bean.HuaWeiOss;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.SysConfigService;
import com.yami.shop.service.QRCodeService;
import com.yami.shop.task.common.model.TaskAccomplishCondition;
import com.yami.shop.task.common.model.TaskDetail;
import com.yami.shop.task.common.model.TaskInviteLog;
import com.yami.shop.common.bean.TaskPageUrl;
import com.yami.shop.task.common.service.TaskAccomplishConditionService;
import com.yami.shop.task.common.service.TaskDetailService;
import com.yami.shop.task.common.service.TaskInviteLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping("/p/task")
@Tag(name = "任务分享二维码生成")
public class QrCodeController {
    @Autowired
    private QRCodeService qrCodeService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private TaskInviteLogService taskInviteLogService;
    @Autowired
    private TaskDetailService taskDetailService;
    @Autowired
    private TaskAccomplishConditionService taskAccomplishConditionService;
    @PostMapping("/QRCode/{taskId}")
    @Operation(summary = "生成任务二维码", description = "生成任务二维码")
    public ServerResponseEntity<String> getQRCode(@PathVariable("taskId") Long taskId) {
        // 邀请人id
        String userId = SecurityUtils.getUser().getUserId();
        String value = sysConfigService.getValue(Constant.TASK_PAGE_URL_CONFIG);
        Gson gson = new Gson();
        TaskPageUrl taskPageUrl = gson.fromJson(value, TaskPageUrl.class);
        Domain domain = sysConfigService.getSysConfigObject(Constant.DOMAIN_CONFIG, Domain.class);
        TaskDetail taskDetail = taskDetailService.getById(taskId);
        String page; //页面地址
        String callBackUrl; // 回调地址
        String inviteCode = IdUtil.randomUUID().replace("-", "").substring(0, 5); // 邀请码
        String content = ""; // 拼接二维码链接
//        String content = domain + registerPage + "?data=" + data;
        switch (taskDetail.getAccomplishType()){
            case 2: // 分享商品、私教、任务、家政
                callBackUrl = "/task/taskId/" + taskId + "/" + userId;
                page = taskPageUrl.getProdDetailPage(); // 商品页
                content = page + "?taskId=" + taskId + "&userId=" + userId + "&prodId=" + taskDetail.getProdId();
                break;
            case 7: // 邀请任务
                page = taskPageUrl.getRegisterPage(); // 注册页
                callBackUrl = "/task/taskId/" + taskId + "/" + userId;
                content = page + "?taskId=" + taskId + "&userId=" + userId + "&inviteCode=" + inviteCode;
                break;
        }
        // 插入一条任务记录
        TaskAccomplishCondition taskAccomplishCondition = new TaskAccomplishCondition();
        taskAccomplishCondition.setTaskId(taskId);
        taskAccomplishCondition.setUserId(userId);
        taskAccomplishCondition.setCreateTime(new Date());
        taskAccomplishCondition.setStatus(1);
        taskAccomplishConditionService.save(taskAccomplishCondition);
        HuaWeiOss aliOss = sysConfigService.getSysConfigObject(Constant.HUAWEI_OBS_CONFIG, HuaWeiOss.class);
        String qrCodeUrl = qrCodeService.generateQRCodeUrl(content, aliOss);
        TaskInviteLog taskInviteLog = new TaskInviteLog();
        taskInviteLog.setTaskId(taskId);
        taskInviteLog.setTaskLink(content);
        taskInviteLog.setUserId(userId);
        taskInviteLog.setInviteCode(inviteCode);
        taskInviteLog.setTaskQrcodeUrl(qrCodeUrl);
        taskInviteLogService.save(taskInviteLog);
        return ServerResponseEntity.success(qrCodeUrl);
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskAppController.java
New file
@@ -0,0 +1,98 @@
package com.yami.shop.task.api.controller;
import cn.hutool.crypto.digest.DigestUtil;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.yami.shop.bean.dto.TaskAppReleaseDto;
import com.yami.shop.bean.model.MarsAdverIncome;
import com.yami.shop.common.config.Constant;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.service.MarsAdverIncomeService;
import com.yami.shop.service.SysConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/taskApp")
@Tag(name = "任务app相关")
@Slf4j
public class TaskAppController {
    @Autowired
    private MarsAdverIncomeService marsAdverIncomeService;
    @Autowired
    private SysConfigService sysConfigService;
    @GetMapping(value = "/release", produces = "text/plain;charset=utf-8")
    @Operation(summary = "app流量释放")
    public String getAppSecret(TaskAppReleaseDto taskAppReleaseDto) {
        log.info("request param:{}", taskAppReleaseDto.toString());
        Map<String, Object> result = new HashMap<>();
        String flag = "fail";
        String appSecret = "76cbf181d9d34650bf494a695cd04f53";
        taskAppReleaseDto.setAppSecret(appSecret);
        String gAmount = taskAppReleaseDto.getGAmount().replaceAll("(\\.\\d*[1-9])0*$|\\.0*$", "$1");
        String signData = taskAppReleaseDto.getAppId() + "-" + taskAppReleaseDto.getUserId() + "-" + gAmount + "-" + taskAppReleaseDto.getAppSecret();
        log.info("signData:{}",signData);
        String sign = DigestUtil.sha256Hex(signData);
        log.info("========sign:{}",sign);
        log.info("request sign:{}", taskAppReleaseDto.getSign());
        if(sign.equals(taskAppReleaseDto.getSign())) {
            //TODO 释放流量入库
            String value = sysConfigService.getValue(Constant.RATE_G_SCORE);
            BigDecimal money = new BigDecimal(taskAppReleaseDto.getGAmount()).divide(new BigDecimal(value));
            MarsAdverIncome marsAdverIncome = MarsAdverIncome.builder()
                    .userId(taskAppReleaseDto.getUserId())
                    .gAmount(taskAppReleaseDto.getGAmount())
                    .appId(taskAppReleaseDto.getAppId())
                    .operateType(taskAppReleaseDto.getOperateType())
                    .sign(taskAppReleaseDto.getSign())
                    .money(money)
                    .recordId(taskAppReleaseDto.getRecordId())
                    .date(new Date())
                    .build();
            boolean save = marsAdverIncomeService.save(marsAdverIncome);
            marsAdverIncomeService.saveUserIncome(marsAdverIncome);
            flag = save? "success" : "fail";
        }else {
            throw new RuntimeException("签名错误");
        }
        result.put("flag", flag);
        return flag;
    }
    public static void main(String[] args) {
        TaskAppReleaseDto taskAppReleaseDto = TaskAppReleaseDto.builder()
                .userId("7677")
                .gAmount("2868.10")
                .appId("66652685")
                .appSecret("76cbf181d9d34650bf494a695cd04f53")
                .sign("b782156cdf82d7832413b5bae02cea23d1751e9bbe337465961d62167f930c22")
                .build();
        String gAmount = taskAppReleaseDto.getGAmount().replaceAll("(\\.\\d*[1-9])0*$|\\.0*$", "$1");
        String signData = taskAppReleaseDto.getAppId() + "-" + taskAppReleaseDto.getUserId() + "-" + gAmount + "-" + taskAppReleaseDto.getAppSecret();
        log.info("signData:{}",signData);
        String sign = DigestUtil.sha256Hex(signData);
        log.info("========sign:{}",sign);
        log.info("request sign:{}", taskAppReleaseDto.getSign());
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskCallBackService.java
New file
@@ -0,0 +1,110 @@
package com.yami.shop.task.api.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.task.common.model.TaskAccomplishCondition;
import com.yami.shop.task.common.model.TaskCommissionLog;
import com.yami.shop.task.common.model.TaskDetail;
import com.yami.shop.task.common.service.TaskAccomplishConditionService;
import com.yami.shop.task.common.service.TaskCommissionLogService;
import com.yami.shop.task.common.service.TaskDetailService;
import com.yami.shop.task.common.service.TaskInviteLogService;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.Objects;
//@RestController
//@RequestMapping("/task/callBack")
//@AllArgsConstructor
@Service
public class TaskCallBackService {
    @Autowired
    private TaskInviteLogService taskInviteLogService;
    @Autowired
    private TaskAccomplishConditionService taskAccomplishConditionService;
    @Autowired
    private TaskDetailService taskDetailService;
    @Autowired
    private TaskCommissionLogService taskCommissionLogService;
    @Autowired
    private UserScoreLogService userScoreLogService;
    @Autowired
    private UserScoreDetailService userScoreDetailService;
    /**
     * 任务回调
     * @return
     */
//    @PostMapping("/{taskId}/{userId}")
//    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity taskCallback(Long taskId, String userId) {
        TaskAccomplishCondition taskAccomplishCondition = taskAccomplishConditionService.getOne(Wrappers.lambdaQuery(TaskAccomplishCondition.class)
                .eq(TaskAccomplishCondition::getTaskId,taskId).eq(TaskAccomplishCondition::getUserId,userId));
        TaskDetail taskDetail = taskDetailService.getById(taskId);
        // 如果是第一次邀请成功
        if (taskAccomplishCondition == null){
            taskAccomplishCondition = new TaskAccomplishCondition();
            taskAccomplishCondition.setTaskId(taskId);
            taskAccomplishCondition.setUserId(userId);
            taskAccomplishCondition.setCreateTime(new Date());
            taskAccomplishCondition.setCompletedNumber(1); //初始完成1次
            taskAccomplishConditionService.save(taskAccomplishCondition);
            return ServerResponseEntity.success();
        }else {
            // 如果邀请完成次数达到了任务设置的完成次数,就要发放佣金
            if (Objects.equals(taskAccomplishCondition.getCompletedNumber() + 1, taskDetail.getAccomplishUpperLimit())) {
                // 修改完成状态
                taskAccomplishCondition.setAccomplishTime(new Date());
                taskAccomplishCondition.setStatus(2);//完成状态
                taskAccomplishCondition.setAwardCommission(taskDetail.getAwardCommission());
                taskAccomplishConditionService.update(taskAccomplishCondition, Wrappers.lambdaUpdate(TaskAccomplishCondition.class));
                // 发放佣金
                TaskCommissionLog taskCommissionLog = new TaskCommissionLog();
                taskCommissionLog.setUserId(userId);
                taskCommissionLog.setCommissionType(taskDetail.getCommissionsType());
                taskCommissionLog.setAmount(taskDetail.getAwardCommission());
                taskCommissionLog.setIoType(1);
                taskCommissionLogService.save(taskCommissionLog);
                // TODO 佣金 0 现金 1 积分 2 幸运值 目前只做了积分,后期加入不同的佣金类型
                switch (taskDetail.getCommissionsType()){
                    case 0:
                        break;
                    case 1:
                        // 佣金操作之前之前先查商家余额看是否足够
                        Long usableScore = userScoreDetailService.getUsableScoreByUserId(taskDetail.getCreateUserId());
                        if (usableScore < taskDetail.getAwardCommission()){
                            return ServerResponseEntity.showFailMsg("商家余额不足");
                        }
                        // 在积分记录表写入一条收入记录
                        UserScoreLog userScoreLog = new UserScoreLog();
                        userScoreLog.setUserId(userId);
                        userScoreLog.setSource(3); // 来源 : 3=任务
                        userScoreLog.setScore(taskDetail.getAwardCommission());
                        userScoreLog.setIoType(1);
                        userScoreLog.setCreateTime(new Date());
                        userScoreLogService.save(userScoreLog);
                        // 在积分详细表加上积分
                        userScoreDetailService.updateScore(userId,taskDetail.getAwardCommission());
                        // 扣除发布任务用户积分
                        userScoreLog.setUserId(taskDetail.getCreateUserId());
                        userScoreLog.setSource(3);
                        userScoreLog.setIoType(0);
                        userScoreLogService.save(userScoreLog);
                        userScoreDetailService.updateScore(taskDetail.getCreateUserId(),-taskDetail.getAwardCommission());
                        break;
                    case 2:
                        break;
                }
                return ServerResponseEntity.success();
            } else {
                taskAccomplishConditionService.modifyCompletedNumber(taskId, userId);
                return ServerResponseEntity.success();
            }
        }
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskController.java
New file
@@ -0,0 +1,389 @@
package com.yami.shop.task.api.controller;
import cn.hutool.core.date.DateUtil;
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.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.shop.bean.enums.ScoreLogType;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.ScoreConfigParam;
import com.yami.shop.bean.param.ScoreExpireParam;
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.security.api.util.SecurityUtils;
import com.yami.shop.service.*;
import com.yami.shop.service.impl.SysConfigServiceImpl;
import com.yami.shop.task.common.bean.TaskFeaturedFirstScore;
import com.yami.shop.task.common.bean.TaskManage;
import com.yami.shop.task.common.model.*;
import com.yami.shop.task.common.param.TaskAccomplishConditionParam;
import com.yami.shop.task.common.param.TaskDetailParam;
import com.yami.shop.task.common.param.TaskSignInParam;
import com.yami.shop.task.common.service.*;
import com.yami.shop.task.common.vo.TaskIncomeVO;
import com.yami.shop.task.common.vo.TaskRuleVO;
import com.yami.shop.task.common.vo.TaskVO;
import com.yami.shop.user.common.dto.ScoreDataDto;
import com.yami.shop.user.common.model.UserLevel;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections4.CollectionUtils;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
@RestController
@RequestMapping("/p/task")
@Tag(name = "任务大厅接口")
public class TaskController {
    @Autowired
    private TaskDetailService taskDetailService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private TaskSignInCommissionService taskSignInCommissionService;
    @Autowired
    private TaskSignInLogService taskSignInLogService;
    @Autowired
    private TaskAccomplishConditionService taskAccomplishConditionService;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private TaskUserRelationService taskUserRelationService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UserScoreLogService userScoreLogService;
    @Autowired
    private UserScoreDetailService userScoreDetailService;
    @Autowired
    private TaskRefreshLogService taskRefreshLogService;
    @Autowired
    private SysConfigServiceImpl sysConfigService;
    @Autowired
    private UserService userService;
    @Autowired
    private CdnUserWalletService cdnUserWalletService;
    @Autowired
    private CdnFlowService cdnFlowService;
    @Autowired
    private UserExtensionService userExtensionService;
    @Autowired
    private UserScoreLogService scoreLogService;
    @GetMapping("/info")
    @Operation(summary = "任务释放列表信息", description = "任务列表信息")
    public ServerResponseEntity<List<TaskDetail>> getShopList() {
        String userId = SecurityUtils.getUser().getUserId();
        List<TaskDetail> taskDetail = taskDetailService.getTaskDetailList(userId);
        return ServerResponseEntity.success(taskDetail);
    }
    @GetMapping("/taskRefreshLog/{taskId}")
    @Operation(summary = "任务刷新记录", description = "任务刷新记录")
    public ServerResponseEntity<Integer> getTaskRefreshLog(@PathVariable("taskId") Long taskId) {
        Integer taskRefreshLog = taskRefreshLogService.getRefreshLog(taskId, SecurityUtils.getUser().getUserId());
        return ServerResponseEntity.success(taskRefreshLog != null ? taskRefreshLog : 0);
    }
//    @GetMapping("/page")
    @Operation(summary = "分页查询任务列表信息", description = "分页查询任务列表信息")
    public ServerResponseEntity<IPage<TaskDetail>> getPurchaseProdPage(PageParam<TaskDetail> page, @ParameterObject TaskDetail taskDetail) {
        LambdaQueryWrapper<TaskDetail> condition = Wrappers.lambdaQuery(TaskDetail.class).eq(TaskDetail::getIsFinish, 0);
        PageParam<TaskDetail> paged = taskDetailService.page(page, condition);
        Integer taskConditionNum = 0;
        for (TaskDetail taskDetail1 : paged.getRecords()) {
            // 获取被邀请人的userId
            List<TaskUserRelation> list = taskUserRelationService.list(Wrappers.lambdaQuery(TaskUserRelation.class)
                    .eq(TaskUserRelation::getTaskId, taskDetail1.getTaskId())
                    .eq(TaskUserRelation::getInviterUserId, SecurityUtils.getUser().getUserId()));
            if (taskDetail.getGiveConditionSql() != null && !taskDetail.getGiveConditionSql().equals("")) {
                if (!list.isEmpty()) {
                    for (TaskUserRelation taskUserRelation : list) {
                        taskConditionNum += taskDetailService.executeTaskGiveConditionSql(taskDetail1.getGiveConditionSql(), taskUserRelation.getInviteeUserId(), taskDetail1.getTaskId()).getTaskConditionNum();
                    }
                }
            }
            taskDetail1.setTaskConditionNum(taskConditionNum);
        }
        return ServerResponseEntity.success(paged);
    }
    @GetMapping("/signIn/logV2")
    @Operation(summary = "查看积分中心信息" , description = "查看积分中心信息")
    public ServerResponseEntity<ScoreDataDto> scoreInfo() {
        ScoreDataDto scoreDataDto = new ScoreDataDto();
        String userId = SecurityUtils.getUser().getUserId();
        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
        // 0.计算过期时间
        ScoreExpireParam scoreExpireParam = sysConfigService.getSysConfigObject(Constant.SCORE_EXPIRE, ScoreExpireParam.class);
        if (Objects.isNull(scoreParam)) {
            return ServerResponseEntity.success();
        }
        Integer year = Objects.isNull(scoreExpireParam) ? 0 : scoreExpireParam.getExpireYear();
        ArrayList<Integer> signInScores = new ArrayList<>();
        for (String s : scoreParam.getSignInScoreString().trim().split(StrUtil.COMMA)) {
            Integer signInScore = Integer.valueOf(s);
            signInScores.add(signInScore);
        }
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, userId));
        if (userExtension == null) {
            return ServerResponseEntity.success();
        }
        // 查询连续签到天数不大于0并且没有连续签到初始化为0
        boolean isContinuousSign = !isSignIn(userId, DateUtil.offsetDay(DateUtil.date(),-1)) && !isSignIn(userId,DateUtil.date())
                && (Objects.isNull(userExtension.getSignDay()) || userExtension.getSignDay() != 0);
        if(isContinuousSign) {
            userExtension.setSignDay(0);
            userExtensionService.updateById(userExtension);
        }
        UserScoreDetail userScoreDetail = userScoreDetailService.getOne(new LambdaQueryWrapper<UserScoreDetail>().eq(UserScoreDetail::getUserId, userId)
                .eq(UserScoreDetail::getStatus, -1).orderByDesc(UserScoreDetail::getExpireTime).last("limit 1"));
        scoreDataDto.setIsRegister(1);
        scoreDataDto.setExpireScore(Objects.nonNull(userScoreDetail) ? userScoreDetail.getUsableScore() : 0L);
        scoreDataDto.setExpireYear(year);
        scoreDataDto.setScoreExpireSwitch(scoreExpireParam.getScoreExpireSwitch());
        scoreDataDto.setGrowth(userExtension.getGrowth());
        scoreDataDto.setScore(userExtension.getScore());
        scoreDataDto.setScoreList(signInScores);
        scoreDataDto.setRegisterScore(scoreParam.getRegisterScore());
        scoreDataDto.setShopScore(scoreParam.getShopGetScore());
        scoreDataDto.setIsSignIn(isSignIn(userId, DateUtil.date()) ? 1 : 0);
        scoreDataDto.setLevelType(userExtension.getLevelType());
        //计算签到天数
        int count = userExtension.getSignDay() <= 0 ? 1 : userExtension.getSignDay();
        // 如果不为第一天签到或者大于等于第七天的签到,+1
        if (userExtension.getSignDay() != 0 && !isSignIn(userId, DateUtil.date())) {
            count++;
        }
        scoreDataDto.setSignInCount(count);
        return ServerResponseEntity.success(scoreDataDto);
    }
    /**
     * 是否已经签到
     *
     * @param userId
     * @param date
     * @return
     */
    private boolean isSignIn(String userId, Date date) {
        List<UserScoreLog> scoreList = scoreLogService.list(new LambdaQueryWrapper<UserScoreLog>().eq(UserScoreLog::getSource, ScoreLogType.SIGN_IN.value())
                .ge(UserScoreLog::getCreateTime, DateUtil.beginOfDay(date))
                .le(UserScoreLog::getCreateTime, DateUtil.endOfDay(date))
                .eq(UserScoreLog::getUserId, userId));
        return CollectionUtils.isNotEmpty(scoreList);
    }
    @GetMapping("/signIn/log")
    @Operation(summary = "签到相关接口", description = "签到相关接口")
    public ServerResponseEntity<TaskSignInParam> getSignInInfo() {
        return  taskSignInLogService.getSignInInfo(SecurityUtils.getUser().getUserId());
    }
    @PostMapping("/do/signIn")
    @Operation(summary = "用户签到", description = "用户签到")
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity doSignIn() {
        Date date = new Date();
        String userId = SecurityUtils.getUser().getUserId();
        TaskSignInCommission taskSignIn = taskSignInCommissionService.getTaskSignIn();
        TaskSignInLog one = taskSignInLogService.getOne(Wrappers.lambdaQuery(TaskSignInLog.class)
                .eq(TaskSignInLog::getUserId, userId)
                .eq(TaskSignInLog::getSignInId, taskSignIn.getId())
                .like(TaskSignInLog::getSignInTime, new SimpleDateFormat("yyyy-MM-dd").format(date)));
        if (one != null) {
            if (one.getIsSignIn() == 1) {
                return ServerResponseEntity.showFailMsg("今日已签到");
            }
        }else {
            taskSignInLogService.initializeSignInLog(userId, taskSignIn.getId());
            one = taskSignInLogService.getOne(Wrappers.lambdaQuery(TaskSignInLog.class)
                    .eq(TaskSignInLog::getUserId, userId)
                    .eq(TaskSignInLog::getSignInId, taskSignIn.getId())
                    .like(TaskSignInLog::getSignInTime, new SimpleDateFormat("yyyy-MM-dd").format(date)));
        }
        Long commission = one.getMoney();
        Boolean b = taskSignInLogService.modifySignInLog(userId, taskSignIn.getId());
        if (b){
            CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.lambdaQuery(CdnUserWallet.class).eq(CdnUserWallet::getUserId, userId).eq(CdnUserWallet::getWalletId, 11));
            Task task = taskService.getOne(Wrappers.lambdaQuery(Task.class).like(Task::getTaskTitle, "%签到%"));
            // 发放奖励
            CdnFlow cdnFlow = new CdnFlow();
            cdnFlow.setUserId(userId);
            cdnFlow.setFlownameId(7);
            cdnFlow.setMoney(BigDecimal.valueOf(commission));
            cdnFlow.setMemo("签到奖励");
            cdnFlow.setDate(date);
            cdnFlow.setCreateTime(date);
            cdnFlow.setWalletId(11);
            cdnFlow.setOldmoney(cdnUserWallet.getMoney());
            cdnFlow.setBizData(task.getTaskId());
            cdnFlowService.save(cdnFlow);
            cdnUserWallet.setMoney(cdnUserWallet.getMoney().add(new BigDecimal(commission)));
            cdnUserWallet.setUpdateTime(date);
            cdnUserWalletService.updateById(cdnUserWallet);
            return ServerResponseEntity.success();
        }
        return ServerResponseEntity.showFailMsg("签到失败");
    }
    @PostMapping("/award/log")
    @Operation(summary = "奖励记录", description = "奖励记录")
    public ServerResponseEntity<List<TaskAccomplishConditionParam>> getAwardLog() {
        String userId = SecurityUtils.getUser().getUserId();
        return ServerResponseEntity.success(taskAccomplishConditionService.getAccomplishConditionByUserId(userId));
    }
    @GetMapping("/detail")
    @Operation(summary = "任务详情", description = "任务详情")
    public ServerResponseEntity<TaskDetailParam> getTaskDetail(@RequestParam("taskId") Long taskId) {
        String userId = SecurityUtils.getUser().getUserId();
        User user = userService.getUserByUserId(userId);
        TaskDetail taskDetail = taskDetailService.getById(taskId);
        TaskDetailParam taskDetailParam = new TaskDetailParam();
        taskDetailParam.setTaskDetail(taskDetail);
        if (taskDetail.getTaskType() == 0) { //商家任务
            taskDetailParam.setShop(shopDetailService.getShopDetailByShopId(productService.getById(taskDetail.getProdId()).getShopId()));
            Product product = productService.getOne(Wrappers.lambdaQuery(Product.class)
                    .eq(Product::getProdId, taskDetail.getProdId()));
            taskDetailParam.setProduct(product);
        }
        taskDetailParam.setUserType(user.getUserType());
        taskDetailParam.setGrandTotalCommission(taskAccomplishConditionService.grandCommissionCount(taskId, null));
        taskDetailParam.setMyGetTaskCommission(taskAccomplishConditionService.grandCommissionCount(taskId, userId));
        taskDetailParam.setTaskAccomplishLog(taskAccomplishConditionService.getList(taskId, userId));
        return ServerResponseEntity.success(taskDetailParam);
    }
    @GetMapping("/getFeaturedFirstScore")
    @Operation(summary = "获取推荐位所需积分", description = "获取推荐位所需积分")
    public ServerResponseEntity<TaskFeaturedFirstScore> getFeaturedFirstScore() {
        TaskFeaturedFirstScore featuredFirstConfig = sysConfigService.getSysConfigObject("FEATURED_FIRST_CONFIG", TaskFeaturedFirstScore.class);
        String userId = SecurityUtils.getUser().getUserId();
        featuredFirstConfig.setCurrentScore(userScoreDetailService.getUsableScoreByUserId(userId));
        return ServerResponseEntity.success(featuredFirstConfig);
    }
    @PutMapping("/addTask")
    @Operation(summary = "修改商品推广任务", description = "修改商品推广任务")
    public ServerResponseEntity addTask(@RequestBody TaskDetail taskDetail) {
        if (taskDetail.getTaskId() != null) {
            taskDetailService.updateById(taskDetail);
            return ServerResponseEntity.success();
        }
        if (taskDetail.getTaskType() == 0){ //商家任务
            Product product = productService.getProductById(taskDetail.getProdId());
            taskDetail.setTaskTitle(product.getProdName());
            taskDetail.setCreateUserId(SecurityUtils.getUser().getUserId());
            taskDetail.setCreateTime(new Date());
            taskDetail.setGiveConditionSql("LEFT JOIN (SELECT ttur.invitee_user_id,COUNT(tor.order_number) AS taskConditionNum FROM tz_task_user_relation ttur JOIN tz_order tor ON tor.user_id = ttur.invitee_user_id JOIN tz_order_item toi ON toi.order_number LIKE tor.order_number JOIN tz_prod tp ON tp.prod_id = toi.prod_id WHERE\n" +
                    " tor.status = 5 GROUP BY ttur.invitee_user_id ) AS condition_sql ON condition_sql.invitee_user_id = #{userId}");
            taskDetailService.save(taskDetail);
        }
        return ServerResponseEntity.success();
    }
    @GetMapping("/getReleaseTask")
    @Operation(summary = "获取推广管理任务", description = "获取推广管理任务")
    public ServerResponseEntity<List<TaskManage>> getReleaseTask(@Parameter(name = "status", description = "查询进行中/已关闭任务 进行中 0 已关闭 1") Integer status) {
        String userId = SecurityUtils.getUser().getUserId();
        List<TaskManage> task = new ArrayList<>();
        if (status == 0) {
            task = taskDetailService.getReleaseTask(userId, status);
        }
        return ServerResponseEntity.success(task);
    }
    @GetMapping("/getTaskByUserId")
    @Operation(description = "查询用户发布的任务", summary = "查询用户发布的任务")
    public ServerResponseEntity<List<TaskDetail>> getTaskByUserId() {
        String userId = SecurityUtils.getUser().getUserId();
        return ServerResponseEntity.success(taskDetailService.list(Wrappers.lambdaQuery(TaskDetail.class).eq(TaskDetail::getCreateUserId, userId)));
    }
    @PutMapping("/modifyTaskStatus/{taskId}/{status}")
    @Operation(summary = "修改商品推广任务状态", description = "修改商品推广任务状态")
    public ServerResponseEntity modifyTaskStatus(@PathVariable("taskId") Long taskId, @PathVariable("status") Integer status) {
        TaskDetail taskDetail = new TaskDetail();
        taskDetail.setTaskId(taskId);
        taskDetail.setIsFinish(status);
        boolean b = taskDetailService.updateById(taskDetail);
        if (b) {
            return ServerResponseEntity.success();
        }
        return ServerResponseEntity.showFailMsg("该任务不存在");
    }
    @GetMapping("/page")
    @Operation(summary = "分页查询任务列表信息", description = "分页查询任务列表信息")
    public ServerResponseEntity<IPage<TaskVO>> getTaskPage(
            @RequestParam Integer page,
            @RequestParam Integer size,
            @RequestParam String userId,
            @RequestParam(required = false) Integer taskType
    ) {
        if (userId == "" || userId == null){
            userId = SecurityUtils.getUser().getUserId();
        }
        return taskService.getTaskPage(page, size, userId, taskType);
    }
    @GetMapping("/getTaskRule")
    @Operation(summary = "获取任务规则", description = "获取任务规则")
    @Transactional(rollbackFor = Exception.class)
    public ServerResponseEntity<TaskRuleVO> getTaskRule(@RequestParam("taskId") Long taskId, @RequestParam("userId") String userId) {
        if (userId == "" || userId == null){
            userId = SecurityUtils.getUser().getUserId();
        }
        return taskService.getTaskRule(taskId, userId);
    }
    @GetMapping("/getMyTask")
    @Operation(summary = "获取我的任务", description = "获取我的任务")
    public ServerResponseEntity<List<TaskVO>> getMyTask(@RequestParam(value = "isAvailable",required = false) Boolean isAvailable,@RequestParam(value = "taskId") Long taskId) {
        String userId = SecurityUtils.getUser().getUserId();
        List<TaskVO> taskVOList = taskService.getMyTask(userId, isAvailable,taskId);
        return ServerResponseEntity.success(taskVOList);
    }
    @GetMapping("/getMyIncome")
    @Operation(summary = "获取我的收益", description = "获取我的收益")
    public ServerResponseEntity<TaskIncomeVO> getMyIncome(@RequestParam("walletId") Integer walletId,@RequestParam("taskId") Long taskId){
        String userId = SecurityUtils.getUser().getUserId();
        TaskIncomeVO taskIncomeVO = new TaskIncomeVO();
        taskIncomeVO.setUserId(userId);
        taskIncomeVO.setTodayIncome(cdnFlowService.getEarnings(userId, DateUtil.format(new Date(), "yyyy-MM-dd"),11,taskId));
        taskIncomeVO.setTotalIncome(cdnFlowService.getEarnings(userId,null,11,taskId));
        taskIncomeVO.setYesterdayIncome(cdnFlowService.getEarnings(userId, DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd"),11,taskId));
        CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(Wrappers.<CdnUserWallet>lambdaQuery().eq(CdnUserWallet::getUserId, userId).eq(CdnUserWallet::getWalletId, walletId));
        taskIncomeVO.setBalance(cdnUserWallet.getMoney());
        return ServerResponseEntity.success(taskIncomeVO);
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskFinishConditionController.java
New file
@@ -0,0 +1,81 @@
package com.yami.shop.task.api.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.task.common.model.TaskDetail;
import com.yami.shop.task.common.model.TaskInviteLog;
import com.yami.shop.task.common.model.TaskRefreshLog;
import com.yami.shop.task.common.model.TaskUserRelation;
import com.yami.shop.task.common.service.TaskDetailService;
import com.yami.shop.task.common.service.TaskInviteLogService;
import com.yami.shop.task.common.service.TaskRefreshLogService;
import com.yami.shop.task.common.service.TaskUserRelationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/p/task/finishCondition")
@Tag(name = "判断任务是否完成")
public class TaskFinishConditionController {
    @Autowired
    private TaskDetailService taskDetailService;
    @Autowired
    private TaskInviteLogService taskInviteLogService;
    @Autowired
    private TaskUserRelationService taskUserRelationService;
    @Autowired
    private TaskRefreshLogService taskRefreshLogService;
    @Autowired
    private TaskCallBackService taskCallBackService;
    @GetMapping("/getTaskFinishCondition")
    @Operation(summary = "执行任务赠送条件判断sql", description = "执行任务赠送条件判断sql")
    public ServerResponseEntity getTaskFinishCondition(@RequestParam("taskId") Long taskId) {
        String userId = SecurityUtils.getUser().getUserId();
        TaskUserRelation inviterUser = taskUserRelationService.getInviterUserId(taskId, userId);
        String taskInviterUserId =inviterUser.getInviterUserId();
        TaskDetail task = taskDetailService.getById(taskId);
        TaskInviteLog taskInviteLog = taskInviteLogService.getOne(Wrappers.lambdaQuery(TaskInviteLog.class)
                .eq(TaskInviteLog::getTaskId, taskId)
                .eq(TaskInviteLog::getUserId,taskInviterUserId));
        TaskDetail taskDetail = taskDetailService.executeTaskGiveConditionSql(task.getGiveConditionSql(),userId,taskId);
        if (taskDetail != null) {
            if (taskDetail.getTaskConditionNum() > 0 && taskDetail.getTaskConditionNum().equals(task.getAccomplishUpperLimit()) && taskInviteLog != null) {
                String taskLink = taskInviteLog.getTaskLink();
                // 解析URL参数
                Map<String, String> params = parseUrlParams(taskLink);
                // 提取callBackUrl的值
//                String callBackUrlValue = params.get("callBackUrl");
//                HttpUtil.post(callBackUrlValue, "");
                taskCallBackService.taskCallback(taskId,taskInviterUserId);
                TaskRefreshLog refresh = new TaskRefreshLog();
                refresh.setTaskId(taskId);
                refresh.setRefreshTime(new Date());
                refresh.setUserId(taskInviterUserId);
                taskRefreshLogService.save(refresh);
            }
        }
        return ServerResponseEntity.success();
    }
    private static Map<String, String> parseUrlParams(String urlString) {
        Map<String, String> params = new HashMap<>();
        String[] pairs = urlString.split("&");
        for (String pair : pairs) {
            int idx = pair.indexOf('=');
            if (idx > 0) {
                String key = pair.substring(0, idx);
                String value = pair.substring(idx + 1);
                params.put(key, value);
            }
        }
        return params;
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskReleaseController.java
New file
@@ -0,0 +1,76 @@
package com.yami.shop.task.api.controller;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.CdnConfigService;
import com.yami.shop.service.MarsHandCardService;
import com.yami.shop.task.common.model.Task;
import com.yami.shop.task.common.model.TaskDetail;
import com.yami.shop.task.common.model.TaskProvideUser;
import com.yami.shop.task.common.service.TaskProvideRecordService;
import com.yami.shop.task.common.service.TaskProvideUserService;
import com.yami.shop.task.common.service.TaskService;
import com.yami.shop.task.common.vo.TaskReleaseVO;
import io.swagger.v3.oas.annotations.Operation;
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.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/p/task/release")
@Tag(name = "任务大厅释放接口")
public class TaskReleaseController {
    @Autowired
    private TaskProvideUserService taskProvideUserService;
    @Autowired
    private CdnConfigService cdnConfigService;
    @Autowired
    private TaskProvideRecordService taskProvideRecordService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private MapperFacade mapperFacade;
    @GetMapping("/list")
    @Operation(summary = "任务列表信息", description = "任务列表信息")
    public ServerResponseEntity<List<TaskReleaseVO>> getList() {
        String userId = SecurityUtils.getUser().getUserId();
        String formattedDate = DateUtil.format(new Date(), "yyyy-MM-dd");
        List<TaskProvideUser> taskProvideUsers = taskProvideUserService.list(Wrappers.lambdaQuery(TaskProvideUser.class)
                .eq(TaskProvideUser::getUserId,userId)
                .like(TaskProvideUser::getDateTime,formattedDate)
                .orderByDesc(TaskProvideUser::getCreateTime));
        if (taskProvideUsers.isEmpty()){
            return ServerResponseEntity.showFailMsg("没有任务");
        }
        List<TaskReleaseVO> taskReleaseVOS = new ArrayList<>();
        for (TaskProvideUser taskProvideUser : taskProvideUsers) {
            TaskReleaseVO taskRelease = mapperFacade.map(taskProvideUser, TaskReleaseVO.class);
            Task task = taskService.getById(taskRelease.getTaskId());
            taskRelease.setTaskIcon(task.getTaskIcon());
            taskRelease.setTaskDescription(task.getTaskDescription());
            taskRelease.setTaskTitle(task.getTaskTitle());
            taskReleaseVOS.add(taskRelease);
         }
        return ServerResponseEntity.success(taskReleaseVOS);
    }
    @PostMapping("/init")
    @Operation(summary = "初始化任务", description = "初始化任务")
    public ServerResponseEntity initTask(@RequestBody TaskReleaseVO taskReleaseVO) {
        String userId = SecurityUtils.getUser().getUserId();
        taskProvideUserService.update(Wrappers.lambdaUpdate(TaskProvideUser.class)
                .eq(TaskProvideUser::getId,taskReleaseVO.getId())
                .eq(TaskProvideUser::getUserId,userId)
                .set(TaskProvideUser::getStatus,1)
                .set(TaskProvideUser::getProcess,10));
        return ServerResponseEntity.success();
    }
}
yami-shop-task/yami-shop-task-api/src/main/java/com/yami/shop/task/api/controller/TaskUserBindController.java
New file
@@ -0,0 +1,41 @@
package com.yami.shop.task.api.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.task.common.model.TaskUserRelation;
import com.yami.shop.task.common.service.TaskUserRelationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/p/task/userBind")
@Tag(name = "用户绑定任务")
public class TaskUserBindController {
    @Autowired
    private TaskUserRelationService taskUserRelationService;
    @PostMapping("/bindInviter")
    @Operation(description = "绑定任务邀请人",summary = "绑定任务邀请人")
    public ServerResponseEntity bindInviter(@RequestParam(name = "inviterUserId")String inviterUserId,@RequestParam(name = "taskId") Long taskId){
        String userId = SecurityUtils.getUser().getUserId();
        TaskUserRelation taskUserRelation;
        taskUserRelation = taskUserRelationService.getOne(Wrappers.lambdaQuery(TaskUserRelation.class)
                .eq(TaskUserRelation::getInviterUserId, inviterUserId)
                .eq(TaskUserRelation::getInviteeUserId, userId)
                .eq(TaskUserRelation::getTaskId, taskId));
        if (taskUserRelation == null){
            taskUserRelation = new TaskUserRelation();
            taskUserRelation.setInviterUserId(inviterUserId);
            taskUserRelation.setInviteeUserId(userId);
            taskUserRelation.setTaskId(taskId);
            taskUserRelationService.save(taskUserRelation);
        }
        return ServerResponseEntity.success();
    }
}
yami-shop-task/yami-shop-task-common/pom.xml
New file
@@ -0,0 +1,35 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-task</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-task-common</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-user-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-security-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.22</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
    </dependencies>
</project>
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/TaskInfoDto.java
New file
@@ -0,0 +1,12 @@
package com.yami.shop.task.common;
import lombok.Data;
@Data
public class TaskInfoDto {
    private Long taskId;
    private String userId;
    private String callBackUrl;
    private String inviteCode;
    private Long prodId;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/bean/TaskFeaturedFirstScore.java
New file
@@ -0,0 +1,14 @@
package com.yami.shop.task.common.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TaskFeaturedFirstScore {
    @Schema(description = "当前积分")
    private Long currentScore;
    @Schema(description = "所需积分")
    private Long requiredScore;
    @Schema(description = "推荐天数")
    private Integer featuredDays;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/bean/TaskManage.java
New file
@@ -0,0 +1,17 @@
package com.yami.shop.task.common.bean;
import com.yami.shop.task.common.model.TaskDetail;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TaskManage {
    @Schema(name = "任务标题")
    private TaskDetail taskDetail;
    @Schema(name = "产生购买数")
    private Integer buyNum;
    @Schema(name = "已发佣金")
    private Long awardCommission;
    @Schema(name = "商品单价")
    private Double price;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskAccomplishConditionMapper.java
New file
@@ -0,0 +1,31 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskAccomplishCondition;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.task.common.param.CommissionGrantLogParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Administrator
* @description 针对表【tz_task_accomplish_condition(任务完成情况表)】的数据库操作Mapper
* @createDate 2024-06-15 09:25:49
* @Entity com.yami.shop.task.common.mobel.TaskAccomplishCondition
*/
public interface TaskAccomplishConditionMapper extends BaseMapper<TaskAccomplishCondition> {
    Long getGrandCommissionCount(@Param("taskId") Long taskId,@Param("userId") String userId);
    List<CommissionGrantLogParam> getTaskAccomplishLog();
    boolean updateCompletedNumberByTaskIdAndUserId(@Param("taskId") Long taskId,@Param("userId") String userId);
    List<CommissionGrantLogParam> selectByTaskId(Long taskId);
    List<TaskAccomplishCondition> getTaskAccomplishConditionList(@Param("plish") TaskAccomplishCondition taskAccomplishCondition);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskClickLogMapper.java
New file
@@ -0,0 +1,18 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskClickLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author lyy
* @description 针对表【tz_task_click_log(用户点击任务日志表)】的数据库操作Mapper
* @createDate 2024-09-21 18:33:23
* @Entity com.yami.shop.task.common.model.TaskClickLog
*/
public interface TaskClickLogMapper extends BaseMapper<TaskClickLog> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskCommissionLogMapper.java
New file
@@ -0,0 +1,22 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskCommissionLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
/**
* @author Administrator
* @description 针对表【tz_task_commission_log(佣金支入支出日志表)】的数据库操作Mapper
* @createDate 2024-06-15 09:25:49
* @Entity com.yami.shop.task.common.mobel.TaskCommissionLog
*/
public interface TaskCommissionLogMapper extends BaseMapper<TaskCommissionLog> {
    Long selectYesterdayEarnings(@Param("userId") String userId,@Param("commissionsType") Integer commissionsType);
    Long selectAccumulativeEarnings(@Param("userId") String userId,@Param("commissionsType") Integer commissionsType);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskDetailMapper.java
New file
@@ -0,0 +1,39 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.task.common.bean.TaskManage;
import com.yami.shop.task.common.model.TaskDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Administrator
* @description 针对表【tz_task_detail(任务详情表)】的数据库操作Mapper
* @createDate 2024-06-15 09:25:49
* @Entity com.yami.shop.task.common.model.TaskDetail
*/
public interface TaskDetailMapper extends BaseMapper<TaskDetail> {
    /**
     * 查询任务详情列表
     * @param userId
     * @return
     */
    List<TaskDetail> selectTaskDetailList(String userId);
    /**
     * 查询商家已发布任务
     * @param userId
     * @param status
     * @return
     */
    List<TaskManage> getReleaseTask(@Param("userId") String userId,@Param("status") Integer status);
    TaskDetail executeSelectTaskConditionSql(@Param("giveConditionSql") String giveConditionSql,@Param("userId") String userId,@Param("taskId") Long taskId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskInviteLogMapper.java
New file
@@ -0,0 +1,18 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskInviteLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author Administrator
* @description 针对表【tz_task_invite_log(任务邀请日志表)】的数据库操作Mapper
* @createDate 2024-06-15 09:25:49
* @Entity com.yami.shop.task.common.mobel.TaskInviteLog
*/
public interface TaskInviteLogMapper extends BaseMapper<TaskInviteLog> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskMapper.java
New file
@@ -0,0 +1,25 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.Task;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.task.common.vo.TaskVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author lyy
* @description 针对表【tz_task(任务表)】的数据库操作Mapper
* @createDate 2024-09-21 17:12:45
* @Entity com.yami.shop.task.common.model.Task
*/
public interface TaskMapper extends BaseMapper<Task> {
    List<TaskVO> getMyTask(@Param("userId")String userId,@Param("status") Integer status);
    TaskVO getTask(@Param("userId") String userId,@Param("taskId") Long bizData);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskProvideRecordMapper.java
New file
@@ -0,0 +1,18 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskProvideRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author lyy
* @description 针对表【tz_task_provide_record(任务提供记录)】的数据库操作Mapper
* @createDate 2024-10-08 14:20:06
* @Entity com.yami.shop.task.common.model.TaskProvideRecord
*/
public interface TaskProvideRecordMapper extends BaseMapper<TaskProvideRecord> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskProvideUserMapper.java
New file
@@ -0,0 +1,18 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskProvideUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author lyy
* @description 针对表【tz_task_provide_user(任务分配记录用户关系)】的数据库操作Mapper
* @createDate 2024-10-08 14:20:06
* @Entity com.yami.shop.task.common.model.TaskProvideUser
*/
public interface TaskProvideUserMapper extends BaseMapper<TaskProvideUser> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskRateMapper.java
New file
@@ -0,0 +1,25 @@
package com.yami.shop.task.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.common.util.PageAdapter;
import com.yami.shop.task.common.model.TaskRate;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author zsq
* @description 针对表【tz_task_rate】的数据库操作Mapper
* @createDate 2024-06-26 14:05:30
* @Entity com.yami.shop.task.common.domain.TaskRate
*/
public interface TaskRateMapper extends BaseMapper<TaskRate> {
    List<TaskRate> listPropAndValue(@Param("adapter") PageAdapter pageAdapter,@Param("taskRate") TaskRate taskRate);
    long countPropAndValue(@Param("taskRate") TaskRate taskRate);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskRefreshLogMapper.java
New file
@@ -0,0 +1,20 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskRefreshLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
/**
* @author Administrator
* @description 针对表【tz_task_refresh_log(任务刷新次数日志表)】的数据库操作Mapper
* @createDate 2024-06-25 20:18:34
* @Entity com.yami.shop.task.common.model.TaskRefreshLog
*/
public interface TaskRefreshLogMapper extends BaseMapper<TaskRefreshLog> {
    Integer getTaskRefreshLog(@Param("taskId") Long taskId,@Param("userId") String userId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskRuleMapper.java
New file
@@ -0,0 +1,18 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskRule;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author lyy
* @description 针对表【tz_task_rule(任务规则)】的数据库操作Mapper
* @createDate 2024-09-21 17:12:45
* @Entity com.yami.shop.task.common.model.TaskRule
*/
public interface TaskRuleMapper extends BaseMapper<TaskRule> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskSignInCommissionMapper.java
New file
@@ -0,0 +1,18 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskSignInCommission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author Administrator
* @description 针对表【tz_task_sign_in_commission(签到任务表)】的数据库操作Mapper
* @createDate 2024-06-15 09:25:49
* @Entity com.yami.shop.task.common.mobel.TaskSignInCommission
*/
public interface TaskSignInCommissionMapper extends BaseMapper<TaskSignInCommission> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskSignInLogMapper.java
New file
@@ -0,0 +1,33 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskSignInLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
/**
* @author Administrator
* @description 针对表【tz_task_sign_in_log(签到记录表)】的数据库操作Mapper
* @createDate 2024-06-15 09:25:49
* @Entity com.yami.shop.task.common.mobel.TaskSignInLog
*/
public interface TaskSignInLogMapper extends BaseMapper<TaskSignInLog> {
    /**
     * 初始化7天签到记录
     * @param userId
     * @param signInId
     */
    void insertInitializeSignInLog(@Param("userId") String userId,@Param("signInId") Long signInId);
    /**
     * 更新签到状态为已签
     * @param userId
     * @param id
     * @return
     */
    Boolean updateByIdAndDate(@Param("userId") String userId,@Param("signInId") Long id);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskUserMapper.java
New file
@@ -0,0 +1,20 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
/**
* @author lyy
* @description 针对表【tz_task_user(用户任务表)】的数据库操作Mapper
* @createDate 2024-09-21 17:12:45
* @Entity com.yami.shop.task.common.model.TaskUser
*/
public interface TaskUserMapper extends BaseMapper<TaskUser> {
    Integer updateTaskStatus(@Param("taskId") Long taskId,@Param("status") Integer status,@Param("userId") String userId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/dao/TaskUserRelationMapper.java
New file
@@ -0,0 +1,23 @@
package com.yami.shop.task.common.dao;
import com.yami.shop.task.common.model.TaskUserRelation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.task.common.service.TaskUserRelationService;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* @author Administrator
* @description 针对表【tz_task_user_relation(任务邀请用户关系表)】的数据库操作Mapper
* @createDate 2024-06-19 09:30:46
* @Entity com.yami.shop.task.common.mobel.TaskUserRelation
*/
public interface TaskUserRelationMapper extends BaseMapper<TaskUserRelation> {
    @Select("select * from tz_task_user_relation where task_id = #{taskId} and invitee_user_id = #{userId}")
    TaskUserRelation selectInviterUserId(@Param("taskId") Long taskId,@Param("userId") String userId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/Task.java
New file
@@ -0,0 +1,112 @@
package com.yami.shop.task.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 java.io.Serializable;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * 任务表
 * @TableName tz_task
 */
@TableName(value ="tz_task")
@Data
public class Task implements Serializable {
    /**
     * 任务id
     */
    @TableId(type = IdType.AUTO)
    private Long taskId;
    /**
     * 任务标题
     */
    @Schema(description = "任务标题")
    private String taskTitle;
    /**
     * 排序
     */
    @Schema(description = "排序")
    private Integer sort;
    /**
     * 任务描述
     */
    @Schema(description = "任务描述")
    private String taskDescription;
    /**
     * 任务图标
     */
    @Schema(description = "任务图标")
    private String taskIcon;
    /**
     * 默认任务按钮提示文字
     */
    @Schema(description = "默认任务按钮提示文字")
    private String defaultStatusTip;
    /**
     * 任务类型 0 商家任务 1 平台任务 2 CDN加速任务 3 AI淘金
     */
    @Schema(description = "任务类型 0 商家任务 1 平台任务 2 CDN加速任务 3 AI淘金")
    private Integer taskType;
    /**
     * 任务奖励描述
     */
    @Schema(description = "任务奖励描述")
    private String commissionsDesc;
    /**
     * 目标对象/对象表名:商品,商户
     */
    @Schema(description = "目标对象/对象表名:商品,商户")
    private String objectType;
    /**
     * 目标对象id/对象表主键
     */
    @Schema(description = "目标对象id/对象表主键")
    private String objectId;
    /**
     * 状态/是否有效:0无效,1
     */
    @Schema(description = "状态/是否有效:0无效,1")
    private Integer stauts;
    /**
     * 创建者的用户ID
     */
    @Schema(description = "创建者的用户ID ")
    private String createUserId;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime = new Date();
    /**
     * 更新用户
     */
    @Schema(description = "更新用户")
    private String updateUserId;
    /**
     * 更新时间
     */
    @Schema(description = "更新时间")
    private Date updateTime = new Date();;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskAccomplishCondition.java
New file
@@ -0,0 +1,67 @@
package com.yami.shop.task.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;
@Data
@TableName("tz_task_accomplish_condition")
public class TaskAccomplishCondition implements Serializable {
    /**
     * 任务完成情况id
     */
    @TableId
    @Schema(description = "任务完成情况id")
    private Long id;
    /**
     * 任务id
     */
    @Schema(description = "任务id")
    private Long taskId;
    /**
     * userId
     */
    @Schema(description = "userId")
    private String userId;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime;
    /**
     * 完成状态 0 未完成 1 进行中 2 已完成 3 已结束
     */
    @Schema(description = " 完成状态 0 未完成 1 进行中 2 已完成 3 已结束")
    private Integer status;
    @Schema(description = "已完成次数")
    private Integer completedNumber;
    /**
     * 完成时间
     */
    @Schema(description = "完成时间")
    private Date accomplishTime;
    /**
     * 奖励佣金
     */
    @Schema(description = "奖励佣金")
    private Long awardCommission;
    /**
     * 是否查询今天完成的任务
     */
    @Schema(description = "是否查询今天完成的任务 1:是 0:否")
    @TableField(exist = false)
    private Integer today;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskAppRelease.java
New file
@@ -0,0 +1,35 @@
package com.yami.shop.task.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;
@Data
@TableName("temp_task_app_release")
public class TaskAppRelease {
    /**
     * 任务邀请用户关系表id
     */
    @TableId
    @Schema(description = "任务邀请用户关系表id")
    private Long relationId;
    /**
     * 邀请人userId
     */
    @Schema(description = "邀请者userId")
    private String inviterUserId;
    /**
     * 被邀请者userId
     */
    @Schema(description = "被邀请者userId")
    private String inviteeUserId;
    /**
     * 任务Id
     */
    @Schema(description = "任务Id")
    private Long taskId;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskClickLog.java
New file
@@ -0,0 +1,41 @@
package com.yami.shop.task.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 java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
 * 用户点击任务日志表
 * @TableName tz_task_click_log
 */
@TableName(value ="tz_task_click_log")
@Data
public class TaskClickLog implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 任务id
     */
    private Long taskId;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 创建时间
     */
    private Date createTime;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskCommissionLog.java
New file
@@ -0,0 +1,57 @@
package com.yami.shop.task.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;
@Data
@TableName("tz_task_commission_log")
public class TaskCommissionLog implements Serializable{
    /**
     * 佣金支入支出日志表id
     */
    @TableId
    @Schema(description = "佣金支入支出日志表id")
    private Long id;
    /**
     * 任务id
     */
    @Schema(description = "任务id")
    private Long taskId;
    /**
     * userId
     */
    @Schema(description = "userId")
    private String userId;
    /**
     * 变动佣金额度
     */
    @Schema(description = "变动佣金额度")
    private Long amount;
    /**
     * 出入类型 0 支出 1 收入
     */
    @Schema(description = "出入类型 0 支出 1 收入")
    private Integer ioType;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime;
    /**
     * 佣金类型 0 现金 1 积分 2 幸运值
     */
    @Schema(description = " 佣金类型 0 现金 1 积分 2 幸运值")
    private Integer commissionType;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskDetail.java
New file
@@ -0,0 +1,143 @@
package com.yami.shop.task.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;
@Data
@TableName("tz_task_detail")
public class TaskDetail implements Serializable {
    /**
     * 任务详情表id
     */
    @TableId
    @Schema(description = "任务详情表id")
    private Long taskId;
    /**
     * 任务标题
     */
    @Schema(description = "任务标题")
    private String taskTitle;
    /**
     * 任务详情
     */
    @Schema(description = "任务详情")
    private String taskDescription;
    /**
     * 规则介绍
     */
    @Schema(description = "规则介绍")
    private String rule;
    /**
     * 任务类型 0 商家任务 1 平台任务
     */
    @Schema(description = "任务类型 0 商家任务 1 平台任务")
    private Integer taskType;
    /**
     * 商品id
     */
    @Schema(description = "商品id")
    private Long prodId;
    /**
     * 商家店铺id
     */
    @Schema(description = "商家店铺id")
    private Long shopId;
    /**
     * 创建人用户id
     */
    @Schema(description = "创建人用户id")
    private String createUserId;
    /**
     * 任务总佣金
     */
    @Schema(description = "任务总佣金")
    private Long taskCommissions;
    /**
     * 佣金类型  0 现金 1 积分 2 幸运值
     */
    @Schema(description = "佣金类型  0 现金 1 积分 2 幸运值")
    private Integer commissionsType;
    /**
     * 完成方式 0 签到 1 下单 2 分享 3 关注 4 扫码 5 激活 6 观看 7 邀请
     */
    @Schema(description = "完成方式 0 签到 1 下单 2 分享 3 关注 4 扫码 5 激活 6 观看 7 邀请")
    private Integer accomplishType;
    /**
     * 完成任务可获取佣金
     */
    @Schema(description = "完成任务可获取佣金")
    private Long accessibleCommission;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime;
    /**
     * 任务图标
     */
    @Schema(description = "任务图标")
    private String taskIcon;
    /**
     * 完成任务需做任务次数
     */
    @Schema(description = "完成任务需做任务次数")
    private Integer accomplishUpperLimit;
    /**
     * 任务是否结束 0 未结束 1 已结束
     */
    @Schema(description = "任务是否结束 0 未结束 1 已结束")
    private Integer isFinish;
    /**
     * 任务刷新次数
     */
    @Schema(description = "任务刷新次数")
    private Integer refreshNum;
    /**
     * 完成时间
     */
    @Schema(description = "完成时间")
    @TableField(exist = false)
    private Date accomplishTime;
    /**
     * 任务完成次数
     */
    @Schema(description = "任务完成次数")
    @TableField(exist = false)
    private Integer taskConditionNum = 0;
    /**
     * 奖励佣金
     */
    @Schema(description = "奖励佣金")
    @TableField(exist = false)
    private Long awardCommission;
    /**
     * 任务赠送条件判断sql
     */
    @Schema(description = "任务赠送条件判断sql")
    private String giveConditionSql;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskInviteLog.java
New file
@@ -0,0 +1,56 @@
package com.yami.shop.task.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;
@Data
@TableName("tz_task_invite_log")
public class TaskInviteLog implements Serializable {
    /**
     * 任务邀请日志表id
     */
    @TableId
    @Schema(description = "任务邀请日志表id")
    private Long id;
    /**
     * 任务id
     */
    @Schema(description = "任务id")
    private Long taskId;
    /**
     * 任务生成的链接
     */
    @Schema(description = "任务生成的链接")
    private String taskLink;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime;
    /**
     * 用户id
     */
    @Schema(description = "用户id")
    private String userId;
    /**
     * 新用户邀请码
     */
    @Schema(description = "新用户邀请码")
    private String inviteCode;
    /**
     * 二维码地址
     */
    @Schema(description = "二维码地址")
    private String taskQrcodeUrl;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskProvideRecord.java
New file
@@ -0,0 +1,85 @@
package com.yami.shop.task.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 java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * 任务提供记录
 * @TableName tz_task_provide_record
 */
@TableName(value ="tz_task_provide_record")
@Data
public class TaskProvideRecord implements Serializable {
    /**
     * id
     */
    @TableId(type = IdType.AUTO)
    private Long provideRecordId;
    /**
     * 任务id
     */
    @Schema(description = "任务id")
    private Long taskId;
    /**
     * 类型 1全网通用任务 2
     */
    @Schema(description = "类型 1全网通用任务 2")
    private Integer type;
    /**
     * 周期开始
     */
    @Schema(description = "周期开始")
    private String startTime;
    /**
     * 周期结束
     */
    @Schema(description = "周期结束")
    private String endTime;
    /**
     * 每天次数
     */
    @Schema(description = "每天次数")
    private Integer times;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime;
    /**
     * 更新时间
     */
    @Schema(description = "更新时间")
    private Date updateTime;
    /**
     * 释放百分比
     */
    @Schema(description = "释放百分比")
    private BigDecimal releaseRate;
    @TableField(exist = false)
    @Schema(description = "任务标题")
    private String taskTitle;
    @TableField(exist = false)
    @Schema(description = "任务图标")
    private String taskIcon;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskProvideUser.java
New file
@@ -0,0 +1,77 @@
package com.yami.shop.task.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 java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
/**
 * 任务分配记录用户关系
 * @TableName tz_task_provide_user
 */
@TableName(value ="tz_task_provide_user")
@Data
public class TaskProvideUser implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 任务提供记录id
     */
    private Long provideRecordId;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 日期
     */
    private String dateTime;
    /**
     * 创建日期
     */
    private Date createTime;
    /**
     * 任务id
     */
    private Long taskId;
    /**
     * 状态 0=初始化 1=任务开启 2=50% 3=100% 4=完成
     */
    private Integer status;
    /**
     * 进度
     */
    private Double process;
    /**
     * 开始时间
     */
    private Date startTime;
    /**
     * 释放总值
     */
    private BigDecimal releaseCount;
    /**
     * 本次释放数量
     */
    private BigDecimal releases;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskRate.java
New file
@@ -0,0 +1,58 @@
package com.yami.shop.task.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 io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 *
 * @TableName tz_task_rate
 */
@TableName(value ="tz_task_rate")
@Data
public class TaskRate implements Serializable {
    /**
     * 主键Id
     */
    @TableId(type = IdType.AUTO)
    @Schema(description = "主键Id")
    private Long id;
    /**
     * 任务Id
     */
    @Schema(description = "任务Id")
    private Long taskId;
    /**
     * 加速比(百分比)
     */
    @Schema(description = "加速比(百分比)")
    private Integer liftRatio;
    /**
     * 是否启用
     */
    @Schema(description = "是否启用")
    private Integer isStart;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime;
    /**
     * 任务标题
     */
    @Schema(description = "任务标题")
    @TableField(exist = false)
    private String taskTitle;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskRefreshLog.java
New file
@@ -0,0 +1,41 @@
package com.yami.shop.task.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 java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
 * 任务刷新次数日志表
 * @TableName tz_task_refresh_log
 */
@TableName(value ="tz_task_refresh_log")
@Data
public class TaskRefreshLog implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 任务id
     */
    private Long taskId;
    /**
     * 刷新时间
     */
    private Date refreshTime;
    /**
     * 用户id
     */
    private String userId;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskRule.java
New file
@@ -0,0 +1,119 @@
package com.yami.shop.task.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 java.io.Serializable;
import java.util.Date;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * 任务规则
 * @TableName tz_task_rule
 */
@TableName(value ="tz_task_rule")
@Data
public class TaskRule implements Serializable {
    /**
     * 主键Id
     */
    @TableId(type = IdType.AUTO)
    private Long ruleId;
    /**
     * 规则名称
     */
    private String ruleName;
    /**
     * 任务Id
     */
    private Long taskId;
    /**
     * 任务状态: 0 未开始 1 开启 2 进行中 3 已完成
     */
    private Integer taskStatus;
    /**
     * 状态名称/任务按钮提示文字
     */
    private String taskStatusTip;
    /**
     * 下一个状态
     */
    private Integer nextStatus;
    /**
     * 打开类型:alert,new,newapp
     */
    private String targetOpenType;
    /**
     * 任务执行路由
     */
    private String targetUrl;
    /**
     * 完成条件/where
     */
    private String ruleCondition;
    /**
     * 奖励佣金类型  0 现金 1 积分 2 幸运值
     */
    private String valueType;
    /**
     * 奖励值
     */
    private Integer value;
    /**
     * 是否启用 enable:0/无效 1/启用
     */
    private Integer enable;
    /**
     * 备注
     */
    private String targetRemark;
    /**
     * 创建用户
     */
    private String createUserId;
    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 创建用户
     */
    private String appId;
    /**
     *
     */
    private String appSecret;
    /**
     * app包名
     */
    private String appBagName;
    /**
     * 创建用户
     */
    @TableField(exist = false)
    private String taskTitle;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskSignInCommission.java
New file
@@ -0,0 +1,94 @@
package com.yami.shop.task.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.math.BigDecimal;
import java.util.Date;
@Data
@TableName("tz_task_sign_in_commission")
public class TaskSignInCommission implements Serializable {
    /**
     * 签到任务表id
     */
    @TableId
    @Schema(description = "签到任务表id")
    private Long id;
    /**
     * 签到任务标题
     */
    @Schema(description = "签到任务标题")
    private String signInTitle;
    /**
     * 签到任务详情
     */
    @Schema(description = "签到任务详情")
    private String signInDescription;
    /**
     * 第一天佣金
     */
    @Schema(description = "第一天佣金")
    private Long oneDayCommission;
    /**
     * 第二天佣金
     */
    @Schema(description = "第二天佣金")
    private Long twoDayCommission;
    /**
     * 第三天佣金
     */
    @Schema(description = "第三天佣金")
    private Long threeDayCommission;
    /**
     * 第四天佣金
     */
    @Schema(description = "第四天佣金")
    private Long fourDayCommission;
    /**
     * 第五天佣金
     */
    @Schema(description = "第五天佣金")
    private Long fiveDayCommission;
    /**
     * 第六天佣金
     */
    @Schema(description = "第六天佣金")
    private Long sixDayCommission;
    /**
     * 第七天佣金
     */
    @Schema(description = "第七天佣金")
    private Long sevenDayCommission;
    /**
     * 任务是否结束 0 未结束 1 已结束
     */
    @Schema(description = "任务是否结束 0 未结束 1 已结束")
    private Integer isFinish;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    private Date createTime;
    @Schema(description = "day")
    private Integer day;
    @Schema(description = "reward")
    private BigDecimal reward;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskSignInLog.java
New file
@@ -0,0 +1,65 @@
package com.yami.shop.task.common.model;
import com.baomidou.mybatisplus.annotation.FieldFill;
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.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("tz_task_sign_in_log")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TaskSignInLog implements Serializable {
    /**
     * 签到记录表id
     */
    @TableId
    @Schema(description = "签到记录表id")
    private Long id;
    /**
     * 用户id
     */
    @Schema(description = "用户id")
    private String userId;
    /**
     * 签到任务id
     */
    @Schema(description = "签到任务id")
    private Long signInId;
    /**
     * 签到时间
     */
    @Schema(description = "签到时间")
    private Date signInTime;
    /**
     * 是否已签 0 未签 1 已签
     */
    @Schema(description = "是否已签 0 未签 1 已签")
    private Integer isSignIn;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @Schema(description = "签到")
    private Date signTime;
    @Schema(description = "可获取积分")
    private Long money;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskUser.java
New file
@@ -0,0 +1,87 @@
package com.yami.shop.task.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 java.io.Serializable;
import java.util.Date;
import java.util.List;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * 用户任务表
 * @TableName tz_task_user
 */
@TableName(value ="tz_task_user")
@Data
public class TaskUser implements Serializable {
    /**
     * 关系表主键
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    /**
     * 任务id
     */
    private Long taskId;
    /**
     * 用户ID
     */
    private String userId;
    @TableField(exist = false)
    private String nickName;
    @TableField(exist = false)
    private String userMobile;
    /**
     * 当前状态/关联任务规则中状态规则
     */
    private Integer status;
    /**
     * 当前状态/关联任务规则中状态规则
     */
    @TableField(exist = false)
    private List<Integer> statusLists;
    @TableField(exist = false)
    private List<String> statusNameLists;
    /**
     * 备注
     */
    private String remark;
    /**
     * 创建用户
     */
    private Integer createUserId;
    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
    /**
     * 创建用户
     */
    @TableField(exist = false)
    private String statusName;
    /**
     * 创建用户
     */
    @TableField(exist = false)
    private String taskTitle;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/model/TaskUserRelation.java
New file
@@ -0,0 +1,35 @@
package com.yami.shop.task.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;
@Data
@TableName("tz_task_user_relation")
public class TaskUserRelation {
    /**
     * 任务邀请用户关系表id
     */
    @TableId
    @Schema(description = "任务邀请用户关系表id")
    private Long relationId;
    /**
     * 邀请人userId
     */
    @Schema(description = "邀请者userId")
    private String inviterUserId;
    /**
     * 被邀请者userId
     */
    @Schema(description = "被邀请者userId")
    private String inviteeUserId;
    /**
     * 任务Id
     */
    @Schema(description = "任务Id")
    private Long taskId;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/CommissionGrantLogParam.java
New file
@@ -0,0 +1,21 @@
package com.yami.shop.task.common.param;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
public class CommissionGrantLogParam {
    @Schema(description = "用户名")
    private String userName;
    @Schema(description = "用户头像")
    private String pic;
    @Schema(description = "奖励积分")
    private Long grantCommission;
    @Schema(description = "获取日期")
    private Date grantDate;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/TaskAccomplishConditionParam.java
New file
@@ -0,0 +1,16 @@
package com.yami.shop.task.common.param;
import com.yami.shop.task.common.model.TaskDetail;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
public class TaskAccomplishConditionParam {
    @Schema(description = "任务详情")
    private TaskDetail taskDetail;
    @Schema(description = "完成时间")
    private Date accomplishTime;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/TaskDetailParam.java
New file
@@ -0,0 +1,33 @@
package com.yami.shop.task.common.param;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.task.common.model.TaskDetail;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class TaskDetailParam {
    @Schema(description = "用户类型")
    private Integer userType;
    @Schema(description = "任务详情")
    private TaskDetail taskDetail;
    @Schema(description = "店铺详情")
    private ShopDetail shop;
    @Schema(description = "商品详情")
    private Product product;
    @Schema(description = "累计发放佣金")
    private Long grandTotalCommission;
    @Schema(description = "我获取得佣金")
    private Long myGetTaskCommission;
    @Schema(description = "发放记录")
    private List<CommissionGrantLogParam> taskAccomplishLog;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/param/TaskSignInParam.java
New file
@@ -0,0 +1,41 @@
package com.yami.shop.task.common.param;
import com.yami.shop.task.common.model.TaskSignInCommission;
import com.yami.shop.task.common.model.TaskSignInLog;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class TaskSignInParam {
    @Schema(description = "用户id")
    private String userId;
    @Schema(description = "签到记录")
    private List<TaskSignInLog> taskSignInLog;
    @Schema(description = "今天签到记录")
    private TaskSignInLog todayTaskSignInLog;
    @Schema(description = "签到任务详情信息")
    private TaskSignInCommission taskSignInCommission;
    @Schema(description = "昨日现金收益")
    private Long YesterdayCashEarnings;
    @Schema(description = "累计现金收益")
    private Long AccumulativeCashEarnings;
    @Schema(description = "昨日积分收益")
    private Long YesterdayScoreEarnings;
    @Schema(description = "累计积分收益")
    private Long AccumulativeScoreEarnings;
    @Schema(description = "昨日幸运值收益")
    private Long YesterdayLuckPointEarnings;
    @Schema(description = "累计幸运值收益")
    private Long AccumulativeLuckPointEarnings;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskAccomplishConditionService.java
New file
@@ -0,0 +1,33 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskAccomplishCondition;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.task.common.param.CommissionGrantLogParam;
import com.yami.shop.task.common.param.TaskAccomplishConditionParam;
import java.util.List;
/**
* @author Administrator
* @description 针对表【tz_task_accomplish_condition(任务完成情况表)】的数据库操作Service
* @createDate 2024-06-15 09:25:49
*/
public interface TaskAccomplishConditionService extends IService<TaskAccomplishCondition> {
    List<TaskAccomplishConditionParam> getAccomplishConditionByUserId(String userId);
    Long grandCommissionCount(Long taskId, String userId);
    List<CommissionGrantLogParam> getAccomplishCondition();
    /**
     * 更新任务完成次数
     * @param userId
     * @return
     */
    boolean modifyCompletedNumber(Long taskId, String userId);
    List<CommissionGrantLogParam> getList(Long taskId, String userId);
    List<TaskAccomplishCondition> getTaskAccomplishConditionList(TaskAccomplishCondition taskAccomplishCondition);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskClickLogService.java
New file
@@ -0,0 +1,13 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskClickLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author lyy
* @description 针对表【tz_task_click_log(用户点击任务日志表)】的数据库操作Service
* @createDate 2024-09-21 18:33:23
*/
public interface TaskClickLogService extends IService<TaskClickLog> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskCommissionLogService.java
New file
@@ -0,0 +1,25 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskCommissionLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表【tz_task_commission_log(佣金支入支出日志表)】的数据库操作Service
* @createDate 2024-06-15 09:25:49
*/
public interface TaskCommissionLogService extends IService<TaskCommissionLog> {
    /**
     * 获取昨日任务收益
     * @param userId
     * @return
     */
    Long getYesterdayEarnings(String userId,Integer commissionsType);
    /**
     * 获取任务所有收益
     * @param userId
     * @return
     */
    Long getAccumulativeEarnings(String userId,Integer commissionsType);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskDetailService.java
New file
@@ -0,0 +1,37 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.bean.TaskManage;
import com.yami.shop.task.common.model.TaskDetail;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author Administrator
* @description 针对表【tz_task_detail(任务详情表)】的数据库操作Service
* @createDate 2024-06-15 09:25:49
*/
public interface TaskDetailService extends IService<TaskDetail> {
    /**赠送金额、任务赠送次数条件,任务赠送条件判断sql)
     * 获取任务列表
     * @return
     */
    List<TaskDetail> getTaskDetailList(String userId);
    /**
     * 获取推广任务
     * @param userId
     * @param status
     * @return
     */
    List<TaskManage> getReleaseTask(String userId, Integer status);
    /**
     * 执行任务完成判断sql语句
     * @param giveConditionSql
     * @param userId
     * @param taskId
     * @return
     */
    TaskDetail executeTaskGiveConditionSql(String giveConditionSql,String userId,Long taskId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskInviteLogService.java
New file
@@ -0,0 +1,12 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskInviteLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表【tz_task_invite_log(任务邀请日志表)】的数据库操作Service
* @createDate 2024-06-15 09:25:49
*/
public interface TaskInviteLogService extends IService<TaskInviteLog> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskProvideRecordService.java
New file
@@ -0,0 +1,13 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskProvideRecord;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author lyy
* @description 针对表【tz_task_provide_record(任务提供记录)】的数据库操作Service
* @createDate 2024-10-08 14:20:06
*/
public interface TaskProvideRecordService extends IService<TaskProvideRecord> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskProvideUserService.java
New file
@@ -0,0 +1,13 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskProvideUser;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author lyy
* @description 针对表【tz_task_provide_user(任务分配记录用户关系)】的数据库操作Service
* @createDate 2024-10-08 14:20:06
*/
public interface TaskProvideUserService extends IService<TaskProvideUser> {
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskRateService.java
New file
@@ -0,0 +1,26 @@
package com.yami.shop.task.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.task.common.model.TaskRate;
/**
* @author zsq
* @description 针对表【tz_task_rate】的数据库操作Service
* @createDate 2024-06-26 14:05:30
*/
public interface TaskRateService extends IService<TaskRate> {
    IPage<TaskRate> pagePropAndValue(TaskRate taskRate, PageParam<TaskRate> page);
    TaskRate getTaskRateDetail(Long id);
    void saveRate(TaskRate taskRate);
    void updateRate(TaskRate taskRate);
    void delete(Long id);
    TaskRate  getTaskRateByTaskId(Long taskId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskRefreshLogService.java
New file
@@ -0,0 +1,14 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskRefreshLog;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表【tz_task_refresh_log(任务刷新次数日志表)】的数据库操作Service
* @createDate 2024-06-25 20:18:34
*/
public interface TaskRefreshLogService extends IService<TaskRefreshLog> {
    Integer getRefreshLog(Long taskId, String userId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskRuleService.java
New file
@@ -0,0 +1,25 @@
package com.yami.shop.task.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.task.common.model.TaskRule;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author lyy
* @description 针对表【tz_task_rule(任务规则)】的数据库操作Service
* @createDate 2024-09-21 17:12:45
*/
public interface TaskRuleService extends IService<TaskRule> {
    IPage<TaskRule> getTaskRulePage(PageParam<TaskRule> page, TaskRule taskRule);
    List<TaskRule> getTaskRules(TaskRule taskRule);
    TaskRule getTaskRuleById(Long id);
    Integer saveTaskRule(TaskRule taskRule);
    Integer updateTaskRule(TaskRule taskRule);
    Integer deleteTaskRule(Long id);
    List<TaskRule> selectStatusByTaskId(Long taskId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskService.java
New file
@@ -0,0 +1,26 @@
package com.yami.shop.task.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.task.common.model.Task;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.task.common.vo.TaskRuleVO;
import com.yami.shop.task.common.vo.TaskVO;
import java.util.List;
/**
* @author lyy
* @description 针对表【tz_task(任务表)】的数据库操作Service
* @createDate 2024-09-21 17:12:45
*/
public interface TaskService extends IService<Task> {
    ServerResponseEntity<IPage<TaskVO>> getTaskPage(Integer page, Integer size, String userId, Integer taskType);
    ServerResponseEntity<TaskRuleVO> getTaskRule(Long taskId, String userId);
    List<Task>  getTaskList(Task task);
    List<TaskVO> getMyTask(String userId, Boolean isAvailable, Long taskId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskSignInCommissionService.java
New file
@@ -0,0 +1,18 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskSignInCommission;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表【tz_task_sign_in_commission(签到任务表)】的数据库操作Service
* @createDate 2024-06-15 09:25:49
*/
public interface TaskSignInCommissionService extends IService<TaskSignInCommission> {
    /**
     * 获取任务签到发放佣金额
     * @return
     */
    TaskSignInCommission getTaskSignIn();
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskSignInLogService.java
New file
@@ -0,0 +1,32 @@
package com.yami.shop.task.common.service;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.task.common.model.TaskSignInLog;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.task.common.param.TaskSignInParam;
/**
* @author Administrator
* @description 针对表【tz_task_sign_in_log(签到记录表)】的数据库操作Service
* @createDate 2024-06-15 09:25:49
*/
public interface TaskSignInLogService extends IService<TaskSignInLog> {
    /**
     * 初始化签到记录
     * @param userId
     * @param signInId
     */
    void initializeSignInLog(String userId,Long signInId);
    /**
     * 用户签到
     * @param userId
     * @param id
     */
    Boolean modifySignInLog(String userId, Long id);
    ServerResponseEntity<TaskSignInParam> getSignInInfo(String userId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskUserRelationService.java
New file
@@ -0,0 +1,14 @@
package com.yami.shop.task.common.service;
import com.yami.shop.task.common.model.TaskUserRelation;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表【tz_task_user_relation(任务邀请用户关系表)】的数据库操作Service
* @createDate 2024-06-19 09:30:46
*/
public interface TaskUserRelationService extends IService<TaskUserRelation> {
    TaskUserRelation getInviterUserId(Long taskId, String userId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/TaskUserService.java
New file
@@ -0,0 +1,26 @@
package com.yami.shop.task.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.task.common.model.TaskUser;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author lyy
* @description 针对表【tz_task_user(用户任务表)】的数据库操作Service
* @createDate 2024-09-21 17:12:45
*/
public interface TaskUserService extends IService<TaskUser> {
    IPage<TaskUser> getTaskUserPage(PageParam<TaskUser> page, TaskUser taskUser);
    List<TaskUser> getTaskUsers(TaskUser taskUser);
    TaskUser getTaskUserById(Long id);
    Integer saveTaskUser(TaskUser taskUser);
    Integer updateTaskUser(TaskUser taskUser);
    Integer deleteTaskUser(Long id);
    Integer updateTaskStatus(Long taskId, Integer status, String userId);
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskAccomplishConditionServiceImpl.java
New file
@@ -0,0 +1,76 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.dao.TaskDetailMapper;
import com.yami.shop.task.common.model.TaskAccomplishCondition;
import com.yami.shop.task.common.param.CommissionGrantLogParam;
import com.yami.shop.task.common.param.TaskAccomplishConditionParam;
import com.yami.shop.task.common.service.TaskAccomplishConditionService;
import com.yami.shop.task.common.dao.TaskAccomplishConditionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Administrator
* @description 针对表【tz_task_accomplish_condition(任务完成情况表)】的数据库操作Service实现
* @createDate 2024-06-15 09:25:49
*/
@Service
public class TaskAccomplishConditionServiceImpl extends ServiceImpl<TaskAccomplishConditionMapper, TaskAccomplishCondition>
    implements TaskAccomplishConditionService{
    @Autowired
    private TaskAccomplishConditionMapper taskAccomplishConditionMapper;
    @Autowired
    private TaskDetailMapper taskDetailMapper;
    @Override
    public List<TaskAccomplishConditionParam> getAccomplishConditionByUserId(String userId) {
        List<TaskAccomplishConditionParam> taskAccomplishConditionList = new ArrayList<>();
        List<TaskAccomplishCondition> list = taskAccomplishConditionMapper.selectList(Wrappers.lambdaQuery(TaskAccomplishCondition.class)
                .eq(TaskAccomplishCondition::getUserId,userId)
                .eq(TaskAccomplishCondition::getStatus,2));
        for (int i = 0; i < list.size(); i++) {
            TaskAccomplishConditionParam taskAccomplishConditionParam = new TaskAccomplishConditionParam();
            taskAccomplishConditionParam.setTaskDetail(taskDetailMapper.selectById(list.get(i).getTaskId()));
            taskAccomplishConditionParam.setAccomplishTime(list.get(i).getAccomplishTime());
            taskAccomplishConditionList.add(taskAccomplishConditionParam);
        }
        return taskAccomplishConditionList;
    }
    @Override
    public Long grandCommissionCount(Long taskId, String userId) {
        return taskAccomplishConditionMapper.getGrandCommissionCount(taskId,userId);
    }
    @Override
    public List<CommissionGrantLogParam> getAccomplishCondition() {
        return taskAccomplishConditionMapper.getTaskAccomplishLog();
    }
    @Override
    public boolean modifyCompletedNumber(Long taskId, String userId) {
        return taskAccomplishConditionMapper.updateCompletedNumberByTaskIdAndUserId(taskId,userId);
    }
    @Override
    public List<CommissionGrantLogParam> getList(Long taskId, String userId) {
        return taskAccomplishConditionMapper.selectByTaskId(taskId);
    }
    @Override
    public List<TaskAccomplishCondition> getTaskAccomplishConditionList(TaskAccomplishCondition taskAccomplishCondition) {
        return taskAccomplishConditionMapper.getTaskAccomplishConditionList(taskAccomplishCondition);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskClickLogServiceImpl.java
New file
@@ -0,0 +1,22 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.model.TaskClickLog;
import com.yami.shop.task.common.service.TaskClickLogService;
import com.yami.shop.task.common.dao.TaskClickLogMapper;
import org.springframework.stereotype.Service;
/**
* @author lyy
* @description 针对表【tz_task_click_log(用户点击任务日志表)】的数据库操作Service实现
* @createDate 2024-09-21 18:33:23
*/
@Service
public class TaskClickLogServiceImpl extends ServiceImpl<TaskClickLogMapper, TaskClickLog>
    implements TaskClickLogService{
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskCommissionLogServiceImpl.java
New file
@@ -0,0 +1,35 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.model.TaskCommissionLog;
import com.yami.shop.task.common.service.TaskCommissionLogService;
import com.yami.shop.task.common.dao.TaskCommissionLogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表【tz_task_commission_log(佣金支入支出日志表)】的数据库操作Service实现
* @createDate 2024-06-15 09:25:49
*/
@Service
public class TaskCommissionLogServiceImpl extends ServiceImpl<TaskCommissionLogMapper, TaskCommissionLog>
    implements TaskCommissionLogService{
    @Autowired
    private TaskCommissionLogMapper taskCommissionLogMapper;
    @Override
    public Long getYesterdayEarnings(String userId,Integer commissionsType) {
        return taskCommissionLogMapper.selectYesterdayEarnings(userId,commissionsType);
    }
    @Override
    public Long getAccumulativeEarnings(String userId,Integer commissionsType) {
        return taskCommissionLogMapper.selectAccumulativeEarnings(userId,commissionsType);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskDetailServiceImpl.java
New file
@@ -0,0 +1,45 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.bean.TaskManage;
import com.yami.shop.task.common.model.TaskDetail;
import com.yami.shop.task.common.service.TaskDetailService;
import com.yami.shop.task.common.dao.TaskDetailMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author Administrator
* @description 针对表【tz_task_detail(任务详情表)】的数据库操作Service实现
* @createDate 2024-06-15 09:25:49
*/
@Service
public class TaskDetailServiceImpl extends ServiceImpl<TaskDetailMapper, TaskDetail>
    implements TaskDetailService{
    @Autowired
    private TaskDetailMapper taskDetailMapper;
    @Override
    public List<TaskDetail> getTaskDetailList(String userId) {
        return taskDetailMapper.selectTaskDetailList(userId);
    }
    @Override
    public List<TaskManage> getReleaseTask(String userId, Integer status) {
        return taskDetailMapper.getReleaseTask(userId,status);
    }
    @Override
    public TaskDetail executeTaskGiveConditionSql(String giveConditionSql,String userId,Long taskId) {
//        return taskDetailMapper.executeSql(giveConditionSql);
       return taskDetailMapper.executeSelectTaskConditionSql(giveConditionSql,userId,taskId);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskInviteLogServiceImpl.java
New file
@@ -0,0 +1,21 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.model.TaskInviteLog;
import com.yami.shop.task.common.service.TaskInviteLogService;
import com.yami.shop.task.common.dao.TaskInviteLogMapper;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表【tz_task_invite_log(任务邀请日志表)】的数据库操作Service实现
* @createDate 2024-06-15 09:25:49
*/
@Service
public class TaskInviteLogServiceImpl extends ServiceImpl<TaskInviteLogMapper, TaskInviteLog>
    implements TaskInviteLogService{
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskProvideRecordServiceImpl.java
New file
@@ -0,0 +1,22 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.model.TaskProvideRecord;
import com.yami.shop.task.common.service.TaskProvideRecordService;
import com.yami.shop.task.common.dao.TaskProvideRecordMapper;
import org.springframework.stereotype.Service;
/**
* @author lyy
* @description 针对表【tz_task_provide_record(任务提供记录)】的数据库操作Service实现
* @createDate 2024-10-08 14:20:06
*/
@Service
public class TaskProvideRecordServiceImpl extends ServiceImpl<TaskProvideRecordMapper, TaskProvideRecord>
    implements TaskProvideRecordService{
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskProvideUserServiceImpl.java
New file
@@ -0,0 +1,22 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.model.TaskProvideUser;
import com.yami.shop.task.common.service.TaskProvideUserService;
import com.yami.shop.task.common.dao.TaskProvideUserMapper;
import org.springframework.stereotype.Service;
/**
* @author lyy
* @description 针对表【tz_task_provide_user(任务分配记录用户关系)】的数据库操作Service实现
* @createDate 2024-10-08 14:20:06
*/
@Service
public class TaskProvideUserServiceImpl extends ServiceImpl<TaskProvideUserMapper, TaskProvideUser>
    implements TaskProvideUserService{
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskRateServiceImpl.java
New file
@@ -0,0 +1,63 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.util.PageAdapter;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.task.common.dao.TaskRateMapper;
import com.yami.shop.task.common.model.TaskRate;
import com.yami.shop.task.common.service.TaskRateService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* @author zsq
* @description 针对表【tz_task_rate】的数据库操作Service实现
* @createDate 2024-06-26 14:05:30
*/
@Service
@AllArgsConstructor
public class TaskRateServiceImpl extends ServiceImpl<TaskRateMapper, TaskRate>
    implements TaskRateService{
    private final TaskRateMapper taskRateMapper;
    @Override
    public IPage<TaskRate> pagePropAndValue(TaskRate taskRate, PageParam<TaskRate> page) {
        page.setRecords(taskRateMapper.listPropAndValue(new PageAdapter(page), taskRate));
        page.setTotal(taskRateMapper.countPropAndValue(taskRate));
        return page;
    }
    @Override
    public TaskRate getTaskRateDetail(Long id) {
        return taskRateMapper.selectById(id);
    }
    @Override
    public void saveRate(TaskRate taskRate) {
        taskRate.setCreateTime(new Date());
        taskRateMapper.insert(taskRate);
    }
    @Override
    public void updateRate(TaskRate taskRate) {
        taskRateMapper.updateById(taskRate);
    }
    @Override
    public void delete(Long id) {
        taskRateMapper.deleteById(id);
    }
    @Override
    public TaskRate getTaskRateByTaskId(Long taskId) {
        return taskRateMapper.selectById(taskId);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskRefreshLogServiceImpl.java
New file
@@ -0,0 +1,28 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.model.TaskRefreshLog;
import com.yami.shop.task.common.service.TaskRefreshLogService;
import com.yami.shop.task.common.dao.TaskRefreshLogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表【tz_task_refresh_log(任务刷新次数日志表)】的数据库操作Service实现
* @createDate 2024-06-25 20:18:34
*/
@Service
public class TaskRefreshLogServiceImpl extends ServiceImpl<TaskRefreshLogMapper, TaskRefreshLog>
    implements TaskRefreshLogService{
    @Autowired
    private TaskRefreshLogMapper taskRefreshLogMapper;
    @Override
    public Integer getRefreshLog(Long taskId, String userId) {
        return taskRefreshLogMapper.getTaskRefreshLog(taskId,userId);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskRuleServiceImpl.java
New file
@@ -0,0 +1,101 @@
package com.yami.shop.task.common.service.impl;
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.yami.shop.common.util.PageParam;
import com.yami.shop.task.common.dao.TaskMapper;
import com.yami.shop.task.common.dao.TaskRuleMapper;
import com.yami.shop.task.common.model.Task;
import com.yami.shop.task.common.model.TaskRule;
import com.yami.shop.task.common.model.TaskUser;
import com.yami.shop.task.common.service.TaskRuleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author lyy
* @description 针对表【tz_task_rule(任务规则)】的数据库操作Service实现
* @createDate 2024-09-21 17:12:45
*/
@Service
public class TaskRuleServiceImpl extends ServiceImpl<TaskRuleMapper, TaskRule>
    implements TaskRuleService{
    @Resource
    private TaskRuleMapper taskRuleMapper;
    @Resource
    private TaskMapper taskMapper;
    @Override
    public IPage<TaskRule> getTaskRulePage(PageParam<TaskRule> page, TaskRule taskRule) {
        LambdaQueryWrapper<TaskRule> wrapper = getQueryWrapper(taskRule);
        PageParam<TaskRule> returnPage = taskRuleMapper.selectPage(page, wrapper);
        List<TaskRule> records = returnPage.getRecords();
        for (TaskRule taskRules :records) {
            Task task=taskMapper.selectById(taskRules.getTaskId());
            taskRules.setTaskTitle(task.getTaskTitle());
        }
        returnPage.setRecords(records);
        return returnPage;
    }
    private static LambdaQueryWrapper<TaskRule> getQueryWrapper(TaskRule taskRule) {
        LambdaQueryWrapper<TaskRule> wrapper =  new LambdaQueryWrapper<>();
        wrapper.eq((null != (taskRule.getRuleId())),TaskRule::getRuleId, taskRule.getRuleId());
        wrapper.like(!StringUtils.isEmpty(taskRule.getRuleName()), TaskRule::getRuleName, taskRule.getRuleName());
        wrapper.eq((null != (taskRule.getTaskId())),TaskRule::getTaskId, taskRule.getTaskId());
        wrapper.eq((null != (taskRule.getTaskStatus())),TaskRule::getTaskStatus, taskRule.getTaskStatus());
        wrapper.eq(!StringUtils.isEmpty(taskRule.getValueType()), TaskRule::getValueType, taskRule.getValueType());
        wrapper.eq((null != (taskRule.getEnable())),TaskRule::getEnable, taskRule.getEnable());
        wrapper.orderByDesc(TaskRule::getCreateTime);
        return wrapper;
    }
    @Override
    public List<TaskRule> getTaskRules(TaskRule taskRule) {
        LambdaQueryWrapper<TaskRule> wrapper = getQueryWrapper(taskRule);
        return taskRuleMapper.selectList(wrapper);
    }
    @Override
    public TaskRule getTaskRuleById(Long id) {
        return taskRuleMapper.selectById(id);
    }
    @Override
    public Integer saveTaskRule(TaskRule taskRule) {
        taskRule.setCreateTime(new Date());
        return taskRuleMapper.insert(taskRule);
    }
    @Override
    public Integer updateTaskRule(TaskRule taskRule) {
        return taskRuleMapper.updateById(taskRule);
    }
    @Override
    public Integer deleteTaskRule(Long id) {
        return taskRuleMapper.deleteById(id);
    }
    @Override
    public List<TaskRule> selectStatusByTaskId(Long taskId) {
        TaskRule taskRule = new TaskRule();
        taskRule.setTaskId(taskId);
        LambdaQueryWrapper<TaskRule> wrapper = getQueryWrapper(taskRule);
        return taskRuleMapper.selectList(wrapper);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskServiceImpl.java
New file
@@ -0,0 +1,215 @@
package com.yami.shop.task.common.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.model.CdnFlow;
import com.yami.shop.bean.model.CdnFlowname;
import com.yami.shop.bean.model.CdnWallet;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.service.CdnFlowService;
import com.yami.shop.service.CdnFlownameService;
import com.yami.shop.service.CdnWalletService;
import com.yami.shop.task.common.model.Task;
import com.yami.shop.task.common.model.TaskClickLog;
import com.yami.shop.task.common.model.TaskRule;
import com.yami.shop.task.common.model.TaskUser;
import com.yami.shop.task.common.service.TaskClickLogService;
import com.yami.shop.task.common.service.TaskRuleService;
import com.yami.shop.task.common.service.TaskService;
import com.yami.shop.task.common.dao.TaskMapper;
import com.yami.shop.task.common.service.TaskUserService;
import com.yami.shop.task.common.vo.TaskRuleVO;
import com.yami.shop.task.common.vo.TaskVO;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author lyy
* @description 针对表【tz_task(任务表)】的数据库操作Service实现
* @createDate 2024-09-21 17:12:45
*/
@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task>
    implements TaskService{
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private TaskUserService taskUserService;
    @Autowired
    private TaskRuleService taskRuleService;
    @Autowired
    private TaskClickLogService taskClickLogService;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private CdnFlowService cdnFlowService;
    @Autowired
    private CdnFlownameService cdnFlownameService;
    @Autowired
    private CdnWalletService cdnWalletService;
    @Override
    public ServerResponseEntity<IPage<TaskVO>> getTaskPage(Integer page, Integer size, String userId, Integer taskType) {
        PageParam<Task> p = new PageParam<>();
        p.setCurrent(page);
        p.setSize(size);
        LambdaQueryWrapper<Task> condition = Wrappers.lambdaQuery(Task.class)
                .eq(Task::getStauts, 1)
                .eq(ObjectUtil.isNotEmpty(taskType), Task::getTaskType, taskType)
                .orderByAsc(Task::getSort);
        PageParam<Task> paged = this.page(p, condition);
        IPage<TaskVO> taskVOPage = new Page<>();
        if (paged.getRecords().size() > 0){
            List<TaskVO> taskVOS = new ArrayList<>();
            for (Task task1 : paged.getRecords()) {
                TaskVO vo = mapperFacade.map(task1, TaskVO.class);
                TaskUser taskUsers = taskUserService.getOne(Wrappers.lambdaQuery(TaskUser.class)
                        .eq(TaskUser::getTaskId, task1.getTaskId())
                        .eq(TaskUser::getUserId, userId));
                TaskRule taskRule;
                if (taskUsers == null) {
                    List<TaskRule> list = taskRuleService.list(Wrappers.lambdaQuery(TaskRule.class)
                            .eq(TaskRule::getTaskId, task1.getTaskId())
                            .orderByAsc(TaskRule::getTaskStatus));
                    taskRule = list.get(0);
                }else{
                    taskRule = taskRuleService.getOne(Wrappers.lambdaQuery(TaskRule.class)
                            .eq(TaskRule::getTaskId, task1.getTaskId())
                            .eq(TaskRule::getTaskStatus, taskUsers.getStatus()));
                }
                vo.setTaskTip(taskRule.getTaskStatusTip());
                vo.setTargetOpenType(taskRule.getTargetOpenType());
                vo.setTaskStatus(taskRule.getTaskStatus());
                vo.setAppId(taskRule.getAppId());
                vo.setAppBagName(taskRule.getAppBagName());
                vo.setTargetUrl(taskRule.getTargetUrl());
                taskVOS.add(vo);
            }
            taskVOPage.setRecords(taskVOS);
            taskVOPage.setTotal(paged.getTotal());
            taskVOPage.setCurrent(paged.getCurrent());
            taskVOPage.setSize(paged.getSize());
            return ServerResponseEntity.success(taskVOPage);
        }
        return ServerResponseEntity.success(new PageParam<>());
    }
    @Override
    public ServerResponseEntity<TaskRuleVO> getTaskRule(Long taskId, String userId) {
        TaskUser taskUser = taskUserService.getOne(Wrappers.lambdaQuery(TaskUser.class)
                .eq(TaskUser::getTaskId, taskId)
                .eq(TaskUser::getUserId, userId));
        TaskRule taskRule;
        if (taskUser == null){
            taskRule = taskRuleService.getOne(Wrappers.lambdaQuery(TaskRule.class).eq(TaskRule::getTaskId, taskId).eq(TaskRule::getTaskStatus, 1));
            if (taskRule == null){
                return ServerResponseEntity.showFailMsg("该任务不存在");
            }else{
                taskUser = new TaskUser();
                taskUser.setTaskId(taskId);
                taskUser.setStatus(taskRule.getTaskStatus());
                taskUser.setUserId(userId);
                taskUser.setCreateTime(new Date());
                taskUserService.save(taskUser);
            }
            TaskRuleVO map = mapperFacade.map(taskRule, TaskRuleVO.class);
            map.setStatus(taskUser.getStatus());
            map.setUserId(userId);
            TaskClickLog taskClickLog = new TaskClickLog();
            taskClickLog.setTaskId(taskId);
            taskClickLog.setUserId(userId);
            taskClickLog.setCreateTime(new Date());
            taskClickLogService.save(taskClickLog);
            return ServerResponseEntity.success(map);
        }else{
            taskRule = taskRuleService.getOne(Wrappers.lambdaQuery(TaskRule.class)
                    .eq(TaskRule::getTaskId, taskId)
                    .eq(TaskRule::getTaskStatus, taskUser.getStatus()));
        }
        if (taskRule.getTaskStatus().equals(0)){
            taskUser.setTaskId(taskId);
            taskUser.setStatus(1);
            taskUser.setUserId(userId);
            taskUserService.updateById(taskUser);
        }
        TaskRuleVO map = mapperFacade.map(taskRule, TaskRuleVO.class);
        map.setStatus(taskUser.getStatus());
        map.setUserId(userId);
        TaskClickLog taskClickLog = new TaskClickLog();
        taskClickLog.setTaskId(taskId);
        taskClickLog.setUserId(userId);
        taskClickLog.setCreateTime(new Date());
        taskClickLogService.save(taskClickLog);
        return ServerResponseEntity.success(map);
    }
    @Override
    public List<Task> getTaskList(Task task) {
        LambdaQueryWrapper<Task> queryWrapper = getQueryWrapper(task);
        return taskMapper.selectList(queryWrapper);
    }
    @Override
    public List<TaskVO> getMyTask(String userId, Boolean isAvailable, Long taskId) {
        // 查出收益
        List<Integer> flownameIds = cdnFlownameService.list(Wrappers.lambdaQuery(CdnFlowname.class).like(CdnFlowname::getFlowType, "task")).stream().map(CdnFlowname::getId).collect(Collectors.toList());
        QueryWrapper<CdnFlow> wrapper = new QueryWrapper<CdnFlow>()
                .select("sum(money) as money", "date", "biz_data", "is_available", "wallet_id")
                .eq("user_id", userId)
                .in("flowname_id", flownameIds)
                .eq("biz_data", taskId)
                .orderByDesc("date")
                .groupBy("date")
                .groupBy("wallet_id")
                .groupBy("biz_data")
                .groupBy("is_available");
        if (isAvailable != null){
            wrapper.eq("is_available", isAvailable);
        }
        List<CdnFlow> cdnFlows = cdnFlowService.list(wrapper);
//        List<CdnFlow> cdnFlows = cdnFlowService.listFlows(userId,isAvailable,taskId,flownameIds);
//      List<TaskVO> taskVOList = taskMapper.getMyTask(userId, status);
        List<TaskVO> taskVOList = new ArrayList<>();
        for (CdnFlow cdnFlow : cdnFlows) {
            TaskVO taskVO = taskMapper.getTask(userId,cdnFlow.getBizData());
            Integer money = cdnFlow.getMoney().intValue();
            taskVO.setValue(money);
            CdnWallet wallet = cdnWalletService.getById(cdnFlow.getWalletId());
            taskVO.setValueType(wallet.getName());
            taskVO.setCreateTime(cdnFlow.getDate() + "");
            taskVO.setIsAvailable(cdnFlow.getIsAvailable());
            taskVOList.add(taskVO);
        }
        return taskVOList;
    }
    private static LambdaQueryWrapper<Task> getQueryWrapper(Task task) {
        LambdaQueryWrapper<Task> wrapper =  new LambdaQueryWrapper<>();
        wrapper.eq((null != (task.getTaskId())),Task::getTaskId, task.getTaskId());
        wrapper.like(!StringUtils.isEmpty(task.getTaskTitle()), Task::getTaskTitle, task.getTaskTitle());
        wrapper.eq((null != task.getTaskType()), Task::getTaskType, task.getTaskType());
        wrapper.eq((null != task.getStauts()), Task::getStauts, task.getStauts());
        wrapper.orderByDesc(Task::getCreateTime);
        return wrapper;
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskSignInCommissionServiceImpl.java
New file
@@ -0,0 +1,31 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.model.TaskSignInCommission;
import com.yami.shop.task.common.service.TaskSignInCommissionService;
import com.yami.shop.task.common.dao.TaskSignInCommissionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表【tz_task_sign_in_commission(签到任务表)】的数据库操作Service实现
* @createDate 2024-06-15 09:25:49
*/
@Service
public class TaskSignInCommissionServiceImpl extends ServiceImpl<TaskSignInCommissionMapper, TaskSignInCommission>
    implements TaskSignInCommissionService{
    @Autowired
    private TaskSignInCommissionMapper taskSignInCommissionMapper;
    @Override
    public TaskSignInCommission getTaskSignIn() {
        return taskSignInCommissionMapper.selectOne(Wrappers.lambdaQuery(TaskSignInCommission.class).eq(TaskSignInCommission::getIsFinish,0));
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskSignInLogServiceImpl.java
New file
@@ -0,0 +1,154 @@
package com.yami.shop.task.common.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.service.CdnFlowService;
import com.yami.shop.task.common.model.TaskSignInCommission;
import com.yami.shop.task.common.model.TaskSignInLog;
import com.yami.shop.task.common.param.TaskSignInParam;
import com.yami.shop.task.common.service.TaskCommissionLogService;
import com.yami.shop.task.common.service.TaskSignInCommissionService;
import com.yami.shop.task.common.service.TaskSignInLogService;
import com.yami.shop.task.common.dao.TaskSignInLogMapper;
import com.yami.shop.user.common.service.UserScoreLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
 * @author Administrator
 * @description 针对表【tz_task_sign_in_log(签到记录表)】的数据库操作Service实现
 * @createDate 2024-06-15 09:25:49
 */
@Service
public class TaskSignInLogServiceImpl extends ServiceImpl<TaskSignInLogMapper, TaskSignInLog>
        implements TaskSignInLogService{
    @Autowired
    private TaskSignInLogMapper taskSignInLogMapper;
    @Autowired
    private TaskSignInCommissionService taskSignInCommissionService;
    @Autowired
    private TaskCommissionLogService taskCommissionLogService;
    @Autowired
    private UserScoreLogService userScoreLogService;
    @Autowired
    private CdnFlowService cdnFlowService;
    @Override
    public void initializeSignInLog(String userId,Long signInId) {
        taskSignInLogMapper.insertInitializeSignInLog(userId,signInId);
    }
    @Override
    public Boolean modifySignInLog(String userId, Long id) {
//        return taskSignInLogMapper.updateByIdAndDate(userId,id);
        boolean update = update(Wrappers.lambdaUpdate(TaskSignInLog.class)
                .eq(TaskSignInLog::getUserId, userId)
                .eq(TaskSignInLog::getSignInId, id)
                .eq(TaskSignInLog::getIsSignIn, 0)
                .like(TaskSignInLog::getSignInTime, new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
                .set(TaskSignInLog::getIsSignIn, 1)
                .set(TaskSignInLog::getSignInTime, new Date()));
        return update;
    }
    @Override
    public ServerResponseEntity<TaskSignInParam> getSignInInfo(String userId) {
        TaskSignInCommission taskSignIn = taskSignInCommissionService.getTaskSignIn();
        List<TaskSignInLog> taskSignInLogs = taskSignInLogMapper.selectList(
                Wrappers.lambdaQuery(TaskSignInLog.class)
                        .eq(TaskSignInLog::getUserId, userId)
                        .orderByDesc(TaskSignInLog::getSignInTime));
        if (!taskSignInLogs.isEmpty()) { //初始化用户签到信息
            // 判断是否是第七天
            TaskSignInLog taskSignInLog = taskSignInLogs.get(0);
            Date signInTime = taskSignInLog.getSignInTime();
            Date now = new Date();
            LocalDate signInLocalDate = signInTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate currentLocalDate = now.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            if (currentLocalDate.isAfter(signInLocalDate)){
                taskSignInLogMapper.delete(Wrappers.lambdaQuery(TaskSignInLog.class)
                        .eq(TaskSignInLog::getUserId, userId)
                        .eq(TaskSignInLog::getSignInId, taskSignIn.getId()));
                this.initializeSignInLog(userId, taskSignIn.getId());
            }else {
                Date today = new Date();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(today);
                calendar.add(Calendar.DATE, -1); // 减去一天得到昨天的日期
                Date yesterday = calendar.getTime();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String yesterdayAsString = sdf.format(yesterday);
                TaskSignInLog yesterdayTaskSignInLog = taskSignInLogMapper.selectOne(Wrappers.lambdaQuery(TaskSignInLog.class)
                        .eq(TaskSignInLog::getUserId, userId)
                        .eq(TaskSignInLog::getSignInId, taskSignIn.getId())
                        .like(TaskSignInLog::getSignInTime, yesterdayAsString));
                if (yesterdayTaskSignInLog != null) {
                    if (yesterdayTaskSignInLog.getIsSignIn() == 0) {
                        taskSignInLogMapper.delete(Wrappers.lambdaQuery(TaskSignInLog.class)
                                .eq(TaskSignInLog::getUserId, userId)
                                .eq(TaskSignInLog::getSignInId, taskSignIn.getId()));
                        this.initializeSignInLog(userId, taskSignIn.getId());
                    }
                }
            }
        } else {
            this.initializeSignInLog(userId, taskSignIn.getId());
        }
        TaskSignInParam taskSignInParam = new TaskSignInParam();
        taskSignInParam.setUserId(userId);
        taskSignInParam.setTaskSignInCommission(taskSignIn);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String todayDateString = sdf.format(new Date());
        taskSignInParam.setTodayTaskSignInLog(taskSignInLogMapper.selectOne(Wrappers.lambdaQuery(TaskSignInLog.class)
                .eq(TaskSignInLog::getUserId, userId)
                .eq(TaskSignInLog::getSignInId, taskSignIn.getId())
                .between(TaskSignInLog::getSignInTime, todayDateString + " 00:00:00", todayDateString + " 23:59:59")));
        taskSignInParam.setTaskSignInLog(taskSignInLogMapper.selectList(
                Wrappers.lambdaQuery(TaskSignInLog.class)
                        .eq(TaskSignInLog::getSignInId, taskSignIn.getId())
                        .eq(TaskSignInLog::getUserId, userId)
                        .orderByAsc(TaskSignInLog::getSignInTime)
                )
        );
        taskSignInParam.setYesterdayCashEarnings(taskCommissionLogService.getYesterdayEarnings(userId, 0)); //昨日现金收益
        taskSignInParam.setAccumulativeCashEarnings(taskCommissionLogService.getAccumulativeEarnings(userId, 0)); //累计现金收益
//        taskSignInParam.setYesterdayScoreEarnings(taskCommissionLogService.getYesterdayEarnings(userId, 1)); //昨日积分收益
//        taskSignInParam.setAccumulativeScoreEarnings(taskCommissionLogService.getAccumulativeEarnings(userId, 1)); //累计积分收益
        DateTime dateTime = DateUtil.offsetDay(new Date(), -1);
        taskSignInParam.setYesterdayScoreEarnings(cdnFlowService.getEarnings(userId,DateUtil.format(dateTime, "yyyy-MM-dd"),11,null)); //昨日积分收益
        taskSignInParam.setAccumulativeScoreEarnings(cdnFlowService.getEarnings(userId, null,11,null));//累计积分收益
//        taskSignInParam.setYesterdayScoreEarnings(taskCommissionLogService.getYesterdayEarnings(userId, 3));
        taskSignInParam.setYesterdayLuckPointEarnings(taskCommissionLogService.getYesterdayEarnings(userId, 2)); //昨日幸运值收益
        taskSignInParam.setAccumulativeLuckPointEarnings(taskCommissionLogService.getAccumulativeEarnings(userId, 2)); //累计幸运值收益
        return ServerResponseEntity.success(taskSignInParam);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskUserRelationServiceImpl.java
New file
@@ -0,0 +1,29 @@
package com.yami.shop.task.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.task.common.dao.TaskUserRelationMapper;
import com.yami.shop.task.common.model.TaskUserRelation;
import com.yami.shop.task.common.service.TaskUserRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表【tz_task_user_relation(任务邀请用户关系表)】的数据库操作Service实现
* @createDate 2024-06-19 09:30:46
*/
@Service
public class TaskUserRelationServiceImpl extends ServiceImpl<TaskUserRelationMapper, TaskUserRelation>
    implements TaskUserRelationService{
    @Autowired
    private TaskUserRelationMapper taskUserRelationMapper;
    @Override
    public TaskUserRelation getInviterUserId(Long taskId, String userId) {
        return taskUserRelationMapper.selectInviterUserId(taskId,userId);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/service/impl/TaskUserServiceImpl.java
New file
@@ -0,0 +1,144 @@
package com.yami.shop.task.common.service.impl;
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.yami.shop.bean.model.User;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.service.UserService;
import com.yami.shop.task.common.dao.TaskMapper;
import com.yami.shop.task.common.dao.TaskRuleMapper;
import com.yami.shop.task.common.model.Task;
import com.yami.shop.task.common.model.TaskRule;
import com.yami.shop.task.common.model.TaskUser;
import com.yami.shop.task.common.service.TaskUserService;
import com.yami.shop.task.common.dao.TaskUserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author lyy
* @description 针对表【tz_task_user(用户任务表)】的数据库操作Service实现
* @createDate 2024-09-21 17:12:45
*/
@Service
public class TaskUserServiceImpl extends ServiceImpl<TaskUserMapper, TaskUser>
    implements TaskUserService{
    @Resource
    private TaskUserMapper taskUserMapper;
    @Resource
    private TaskRuleMapper taskRuleMapper;
    @Resource
    private UserService usersService;
    @Resource
    private TaskMapper taskMapper;
    @Override
    public IPage<TaskUser> getTaskUserPage(PageParam<TaskUser> page, TaskUser taskUser) {
        LambdaQueryWrapper<TaskUser> wrapper = getQueryWrapper(taskUser);
        if (wrapper == null){
            return new PageParam<>();
        }
        PageParam<TaskUser> returnPage = taskUserMapper.selectPage(page, wrapper);
        List<TaskUser> records = returnPage.getRecords();
        for (TaskUser taskUsers :records) {
            List<Integer> statusLists = new ArrayList<>();
            List<String> statusNameLists = new ArrayList<>();
            List<TaskRule> taskRules = taskRuleMapper.selectList((Wrappers.lambdaQuery(TaskRule.class)
                    .eq(TaskRule::getTaskId, taskUsers.getTaskId())
                    .eq(TaskRule::getTaskStatus, taskUsers.getStatus())));
            for (TaskRule rule:taskRules) {
                statusLists.add(rule.getTaskStatus());
                statusNameLists.add(rule.getRuleName());
            }
            if(taskRules.size() >0){
                taskUsers.setStatusName(taskRules.get(0).getTaskStatusTip());
            }else{
                taskUsers.setStatusName("/");
            }
            User user = usersService.getUserByUserId(taskUsers.getUserId());
            taskUsers.setNickName(user.getNickName());
            taskUsers.setUserMobile(user.getUserMobile());
            taskUsers.setStatusLists(statusLists);
            taskUsers.setStatusNameLists(statusNameLists);
            Task task=taskMapper.selectById(taskUsers.getTaskId());
            taskUsers.setTaskTitle(task.getTaskTitle());
        }
        returnPage.setRecords(records);
        return returnPage;
    }
    private LambdaQueryWrapper<TaskUser> getQueryWrapper(TaskUser taskUser) {
        LambdaQueryWrapper<TaskUser> wrapper =  new LambdaQueryWrapper<>();
        if (null != (taskUser.getNickName()) && !"".equals(taskUser.getNickName())) {
            List<User> list = usersService.list(Wrappers.lambdaQuery(User.class).like(User::getNickName, taskUser.getNickName()));
            if(list.size()>0){
                List<String> listIds = list.stream().map(User::getUserId).collect(Collectors.toList());
                wrapper.in(TaskUser::getUserId,listIds);
            }else{
                return null;
            }
        }
        if (null != (taskUser.getTaskTitle()) && !"".equals(taskUser.getTaskTitle())) {
            List<Task> list = taskMapper.selectList(Wrappers.lambdaQuery(Task.class).like(Task::getTaskTitle, taskUser.getTaskTitle()));
            if(list.size()>0){
                List<Long> listIds = list.stream().map(Task::getTaskId).collect(Collectors.toList());
                wrapper.in(TaskUser::getTaskId,listIds);
            }else{
                return null;
            }
        }
        wrapper.eq((null != (taskUser.getId())),TaskUser::getId, taskUser.getId());
        wrapper.eq((null != (taskUser.getTaskId())),TaskUser::getTaskId, taskUser.getTaskId());
        wrapper.eq(!StringUtils.isEmpty(taskUser.getUserId()),TaskUser::getUserId, taskUser.getUserId());
        wrapper.eq((null != (taskUser.getStatus())),TaskUser::getStatus, taskUser.getStatus());
        wrapper.eq(!StringUtils.isEmpty(taskUser.getRemark()),TaskUser::getRemark, taskUser.getRemark());
        wrapper.orderByDesc(TaskUser::getCreateTime);
        return wrapper;
    }
    @Override
    public List<TaskUser> getTaskUsers(TaskUser taskUser) {
        LambdaQueryWrapper<TaskUser> wrapper = getQueryWrapper(taskUser);
        return taskUserMapper.selectList(wrapper);
    }
    @Override
    public TaskUser getTaskUserById(Long id) {
        return taskUserMapper.selectById(id);
    }
    @Override
    public Integer saveTaskUser(TaskUser taskUser) {
        taskUser.setCreateTime(new Date());
        return taskUserMapper.insert(taskUser);
    }
    @Override
    public Integer updateTaskUser(TaskUser taskUser) {
        return taskUserMapper.updateById(taskUser);
    }
    @Override
    public Integer deleteTaskUser(Long id) {
        return taskUserMapper.deleteById(id);
    }
    @Override
    public Integer updateTaskStatus(Long taskId, Integer status, String userId) {
        return taskUserMapper.updateTaskStatus(taskId,status,userId);
    }
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskIncomeVO.java
New file
@@ -0,0 +1,26 @@
package com.yami.shop.task.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class TaskIncomeVO {
    @Schema(description = "用户id")
    private String userId;
    @Schema(description = "累计收益")
    private Long totalIncome;
    @Schema(description = "今日收益")
    private Long todayIncome;
    @Schema(description = "昨日收益")
    private Long yesterdayIncome;
    @Schema(description = "钱包余额")
    private BigDecimal balance;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskReleaseVO.java
New file
@@ -0,0 +1,72 @@
package com.yami.shop.task.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class TaskReleaseVO {
    private Long id;
    /**
     * 任务提供记录id
     */
    @Schema(description = "任务提供记录id")
    private Long provideRecordId;
    /**
     * 用户id
     */
    @Schema(description = "用户id")
    private String userId;
    /**
     * 日期
     */
    @Schema(description = "日期")
    private String dateTime;
    /**
     * 创建日期
     */
    @Schema(description = "创建日期")
    private Date createTime;
    /**
     * 任务id
     */
    @Schema(description = "任务id")
    private Long taskId;
    @Schema(description = "任务名称")
    private String taskTitle;
    @Schema(description = "任务描述")
    private String taskDescription;
    @Schema(description = "任务图标")
    private String taskIcon;
    /**
     * 状态 0=初始化 1=任务开启 2=50% 3=100% 4=完成
     */
    @Schema(description = "状态 0=初始化 1=任务开启 2=50% 3=100% 4=完成")
    private Integer status;
    /**
     * 进度
     */
    @Schema(description = "进度")
    private Integer process;
    /**
     * 开始时间
     */
    @Schema(description = "开始时间")
    private Date startTime;
    @Schema(description = "释放金额")
    private BigDecimal releases;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskRuleVO.java
New file
@@ -0,0 +1,81 @@
package com.yami.shop.task.common.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TaskRuleVO {
    /**
     * 规则名称
     */
    @Schema(description = "规则名称")
    private String ruleName;
    /**
     * 任务Id
     */
    @Schema(description = "任务Id")
    private Long taskId;
    /**
     * 状态名称/任务按钮提示文字
     */
    @Schema(description = "状态名称/任务按钮提示文字")
    private String taskStatusTip;
    /**
     * 下一个状态
     */
    @Schema(description = "下一个状态")
    private Integer nextStatus;
    /**
     * 打开类型:alert,new,newapp
     */
    @Schema(description = "打开类型:alert,new,newapp")
    private String targetOpenType;
    /**
     * 任务执行路由
     */
    @Schema(description = "任务执行路由")
    private String targetUrl;
    /**
     * 奖励佣金类型  0 现金 1 积分 2 幸运值
     */
    @Schema(description = "奖励佣金类型  0 现金 1 积分 2 幸运值")
    private String valueType;
    /**
     * 奖励值
     */
    @Schema(description = "奖励值")
    private Integer value;
    /**
     * 是否启用 enable:0/无效 1/启用
     */
    @Schema(description = "是否启用 enable:0/无效 1/启用")
    private Integer enable;
    /**
     * 用户ID
     */
    @Schema(description = "用户ID")
    private String userId;
    /**
     * 备注
     */
    @Schema(description = "备注")
    private String targetRemark;
    /**
     * 当前状态/关联任务规则中状态规则
     */
    @Schema(description = "当前状态 0 未开始 1 开启 2 进行中 3 已完成")
    private Integer status;
}
yami-shop-task/yami-shop-task-common/src/main/java/com/yami/shop/task/common/vo/TaskVO.java
New file
@@ -0,0 +1,107 @@
package com.yami.shop.task.common.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class TaskVO {
    /**
     * 任务id
     */
    @Schema(description = "任务id")
    private Long taskId;
    /**
     * 任务标题
     */
    @Schema(description = "任务标题")
    private String taskTitle;
    /**
     * 任务描述
     */
    @Schema(description = "任务描述")
    private String taskDescription;
    /**
     * 排序
     */
    @Schema(description = "排序")
    private Integer sort;
    /**
     * 任务图标
     */
    @Schema(description = "任务图标")
    private String taskIcon;
    /**
     * 任务按钮提示文字
     */
    @Schema(description = "任务按钮提示文字")
    private String taskTip;
    /**
     * 任务类型 0 商家任务 1 平台任务 2 CDN加速任务 3 AI淘金
     */
    @Schema(description = "任务类型 0 商家任务 1 平台任务 2 CDN加速任务 3 AI淘金")
    private Integer taskType;
    /**
     * 任务奖励描述
     */
    @Schema(description = "任务奖励描述")
    private String commissionsDesc;
    /**
     * 目标对象/对象表名:商品,商户
     */
    @Schema(description = "目标对象/对象表名:商品,商户")
    private String objectType;
    /**
     * 目标对象id/对象表主键
     */
    @Schema(description = "目标对象id/对象表主键")
    private String objectId;
    /**
     * 目标vue路径
     */
    @Schema(description = "目标vue路径")
    private String targetUrl;
    /**
     * 打开类型:alert,new,newapp
     */
    @Schema(description = "打开类型:alert,new,newapp")
    private String targetOpenType;
    @Schema(description = "任务规则状态: 0 未开始 1 开启 2 进行中 3 已完成")
    private Integer taskStatus;
    /**
     * 创建用户
     */
    private String appId;
    /**
     * app包名
     */
    private String appBagName;
    @Schema(description = "奖励值")
    private Integer value;
    @Schema(description = "奖励佣金类型 0 现金 1 积分 2 幸运值")
    private String valueType;
    @Schema(description = "开始时间")
    private String createTime;
    @Schema(description = "是否有效")
    private Boolean isAvailable;
}
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskAccomplishConditionMapper.xml
New file
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.task.common.dao.TaskAccomplishConditionMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskAccomplishCondition">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="status" column="status" jdbcType="INTEGER"/>
            <result property="completedNumber" column="completed_number" jdbcType="INTEGER"/>
            <result property="accomplishTime" column="accomplish_time" jdbcType="TIMESTAMP"/>
            <result property="awardCommission" column="award_commission" jdbcType="BIGINT"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,user_id,create_time,
        status,accomplish_time,award_commission,completed_number
    </sql>
    <update id="updateCompletedNumberByTaskIdAndUserId">
        update tz_task_accomplish_condition
        set completed_number = completed_number + 1 where task_id = #{taskId} and user_id = #{userId}
    </update>
    <select id="getGrandCommissionCount" resultType="java.lang.Long">
        select SUM(award_commission) from tz_task_accomplish_condition
            <where>
                <if test="userId != null">
                    and user_id = #{userId}
                </if>
                <if test="taskId != null">
                    and task_id = #{taskId}
                </if>
            </where>
    </select>
    <select id="getTaskAccomplishLog" resultType="com.yami.shop.task.common.param.CommissionGrantLogParam">
        select * from tz_task_accomplish_condition where status = 2
    </select>
    <select id="selectByTaskId" resultType="com.yami.shop.task.common.param.CommissionGrantLogParam">
        select tu.user_name,tu.pic,ttac.accomplish_time grantDate,ttac.award_commission grantCommission
        from tz_task_accomplish_condition ttac
        INNER JOIN tz_user tu on ttac.user_id = tu.user_id
        where ttac.task_id = #{taskId} and ttac.status = 2
    </select>
    <select id="getTaskAccomplishConditionList"
            resultType="com.yami.shop.task.common.model.TaskAccomplishCondition">
        select ttac.*
        from tz_task_accomplish_condition ttac
        where 1=1
        <if test="plish.taskId != null and plish.taskId != ''">
            and ttac.task_id = #{plish.taskId}
        </if>
        <if test="plish.userId != null and plish.userId != ''">
            and ttac.user_id = #{plish.userId}
        </if>
        <if test="cplish.status != null and cplish.status != ''">
            and ttac.status = #{cplish.status}
        </if>
        <if test="cplish.today != null and cplish.today != ''">
            and DATE_FORMAT(ttac.accomplish_time, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d');
        </if>
    </select>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskClickLogMapper.xml
New file
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.task.common.dao.TaskClickLogMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskClickLog">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,user_id,
        create_time
    </sql>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskCommissionLogMapper.xml
New file
@@ -0,0 +1,33 @@
<?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.task.common.dao.TaskCommissionLogMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskCommissionLog">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
            <result property="amount" column="amount" jdbcType="BIGINT"/>
            <result property="ioType" column="io_type" jdbcType="TINYINT"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="commissionType" column="commission_type" jdbcType="TINYINT"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,user_id,
        amount,io_type,create_time
    </sql>
    <select id="selectYesterdayEarnings" resultType="java.lang.Long">
        select SUM(amount) from tz_task_commission_log
                           where user_id = #{userId}
                           and create_time BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND DATE_SUB(CURDATE(), INTERVAL 0 DAY)
                           and io_type = 1 and commission_type = #{commissionsType};
    </select>
    <select id="selectAccumulativeEarnings" resultType="java.lang.Long">
        select SUM(amount) from tz_task_commission_log
        where user_id = #{userId}
          and io_type = 1
          and commission_type = #{commissionsType};
    </select>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskDetailMapper.xml
New file
@@ -0,0 +1,115 @@
<?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.task.common.dao.TaskDetailMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskDetail">
            <id property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="taskTitle" column="task_title" jdbcType="VARCHAR"/>
            <result property="taskDescription" column="task_description" jdbcType="VARCHAR"/>
            <result property="rule" column="rule" jdbcType="VARCHAR"/>
            <result property="taskType" column="task_type" jdbcType="TINYINT"/>
            <result property="createUserId" column="create_user_id" jdbcType="VARCHAR"/>
            <result property="prodId" column="prod_id" jdbcType="BIGINT"/>
            <result property="shopId" column="shop_id" jdbcType="BIGINT"/>
            <result property="taskCommissions" column="task_commissions" jdbcType="BIGINT"/>
            <result property="commissionsType" column="commissions_type" jdbcType="TINYINT"/>
            <result property="accomplishType" column="accomplish_type" jdbcType="TINYINT"/>
            <result property="accessibleCommission" column="accessible_commission" jdbcType="BIGINT"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="taskIcon" column="task_icon" jdbcType="VARCHAR"/>
            <result property="accomplishUpperLimit" column="accomplish_upper_limit" jdbcType="INTEGER"/>
            <result property="isFinish" column="is_finish" jdbcType="INTEGER"/>
            <result property="giveConditionSql" column="give_condition_sql" jdbcType="VARCHAR"/>
            <result property="refreshNum" column="refresh_num" jdbcType="INTEGER"/>
    </resultMap>
    <sql id="Base_Column_List">
        task_id,task_title,task_description,rule,
        task_type,prodId,shopId,create_user_id,task_commissions,
        commissions_type,accomplish_type,accessible_commission,
        create_time,task_icon,accomplish_upper_limit,is_finish,give_condition_sql,refresh_num
    </sql>
    <select id="executeSql">
        #{giveConditionSql}
    </select>
    <select id="selectTaskDetailList" resultType="com.yami.shop.task.common.model.TaskDetail">
        select ttd.*,ttac.accomplish_time accomplishTime,ttac.award_commission awardCommission from tz_task_detail ttd
        INNER JOIN tz_task_accomplish_condition ttac on ttd.task_id = ttac.task_id
        where ttd.is_finish = 0 and ttac.user_id = #{userId} and ttac.status = 2 and ttd.is_finish = 0
    </select>
    <select id="getReleaseTask" resultType="com.yami.shop.task.common.bean.TaskManage">
        SELECT
            ttd.task_title AS `taskTitle`,
            tp.pic AS `taskIcon`,
            COUNT(DISTINCT toi.order_number) AS `buyNum`,
            SUM(IF(ttac.status = 2 AND ttac.accomplish_time > ttd.create_time, ttac.award_commission, 0)) AS `awardCommission`,
            tp.price AS `price`
        FROM
            tz_task_detail ttd
                INNER JOIN
            tz_prod tp ON ttd.prod_id = tp.prod_id
                LEFT JOIN
            tz_order_item toi ON toi.prod_id = tp.prod_id AND EXISTS (
                SELECT 1
                FROM tz_order tro
                WHERE toi.order_number = tro.order_number AND tro.pay_time > ttd.create_time
            )
                LEFT JOIN
            tz_task_accomplish_condition ttac ON ttac.task_id = ttd.task_id AND ttac.accomplish_time > ttd.create_time
        WHERE
            ttd.create_user_id = #{userId}
          AND ttd.is_finish = #{status}
        GROUP BY
            ttd.task_title, tp.pic, tp.price;
    </select>
    <select id="executeSelectTaskConditionSql" resultType="com.yami.shop.task.common.model.TaskDetail">
        SELECT
        ttd.*,
        <if test="giveConditionSql != null and giveConditionSql != ''">
            condition_sql.taskConditionNum
        </if>
        FROM
        tz_task_detail ttd
        <if test="giveConditionSql != null and giveConditionSql != ''">
            #{giveConditionSql} AS condition_sql ON condition_sql.invitee_user_id = #{userId}
        </if>
        WHERE
        ttd.task_id = #{taskId}
        AND EXISTS (
        SELECT 1
        FROM tz_task_user_relation ttur_inner
        WHERE ttur_inner.invitee_user_id = #{userId} AND ttur_inner.task_id = #{taskId}
        );
    </select>
    <select id="selectProdTaskCondition" resultType="com.yami.shop.task.common.model.TaskDetail">
        SELECT
            ttd.*,
            condition_sql.taskConditionNum
        FROM
            tz_task_detail ttd
                LEFT JOIN (
                SELECT
                    ttur.invitee_user_id,
                    COUNT(tor.order_number) AS taskConditionNum
                FROM
                    tz_task_user_relation ttur
                        JOIN tz_order tor ON tor.user_id = ttur.invitee_user_id
                        JOIN tz_order_item toi ON toi.order_number LIKE tor.order_number
                        JOIN tz_prod tp ON tp.prod_id = toi.prod_id
                WHERE
                    tor.status = 5
                GROUP BY
                    ttur.invitee_user_id
            ) AS condition_sql ON condition_sql.invitee_user_id = #{userId}
        WHERE
            ttd.task_id = #{taskId}
          AND EXISTS (
            SELECT 1
            FROM tz_task_user_relation ttur_inner
            WHERE ttur_inner.invitee_user_id = #{userId} AND ttur_inner.task_id = #{taskId}
        );
    </select>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskInviteLogMapper.xml
New file
@@ -0,0 +1,19 @@
<?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.task.common.dao.TaskInviteLogMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskInviteLog">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="taskLink" column="task_link" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
            <result property="inviteCode" column="invite_code" jdbcType="VARCHAR"/>
            <result property="taskQrcodeUrl" column="task_qrcode_url" jdbcType="VARCHAR"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,task_link,create_time,user_id,invite_code,task_qrcode_url
    </sql>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskMapper.xml
New file
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.task.common.dao.TaskMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.Task">
            <id property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="taskTitle" column="task_title" jdbcType="VARCHAR"/>
            <result property="sort" column="sort" jdbcType="INTEGER"/>
            <result property="taskDescription" column="task_description" jdbcType="VARCHAR"/>
            <result property="taskIcon" column="task_icon" jdbcType="VARCHAR"/>
            <result property="defaultStatusTip" column="default_status_tip" jdbcType="VARCHAR"/>
            <result property="taskType" column="task_type" jdbcType="TINYINT"/>
            <result property="commissionsDesc" column="commissions_desc" jdbcType="VARCHAR"/>
            <result property="objectType" column="object_type" jdbcType="VARCHAR"/>
            <result property="objectId" column="object_id" jdbcType="VARCHAR"/>
            <result property="stauts" column="stauts" jdbcType="INTEGER"/>
            <result property="createUserId" column="create_user_id" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateUserId" column="update_user_id" jdbcType="VARCHAR"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        task_id,task_title,sort,
        task_description,task_icon,default_status_tip,
        task_type,commissions_desc,object_type,
        object_id,stauts,create_user_id,
        create_time,update_user_id,update_time
    </sql>
    <select id="getMyTask" resultType="com.yami.shop.task.common.vo.TaskVO">
        select t.*,
        tur.task_status_tip as taskTip,
        tur.task_status as taskStatus,
        tur.value as value ,
        tur.value_type as valueType ,
        tu.create_time as createTime
        from tz_task t
        left join tz_task_user tu on tu.task_id = t.task_id and tu.user_id = #{userId}
        left join tz_task_rule tur on tur.task_id = t.task_id and tur.task_status = tu.status
        where t.stauts = 1
        <if test="status != null">
        and tu.status = #{status}
        </if>
        order by tur.create_time desc
    </select>
    <select id="getTask" resultType="com.yami.shop.task.common.vo.TaskVO">
        select t.*,
        tur.task_status_tip as taskTip,
        tur.task_status as taskStatus,
        tur.value as value ,
        tur.value_type as valueType ,
        tu.create_time as createTime
        from tz_task t
        left join tz_task_user tu on tu.task_id = t.task_id and tu.user_id = #{userId}
        left join tz_task_rule tur on tur.task_id = t.task_id and tur.task_status = tu.status
        where t.stauts = 1
        <if test="taskId != null">
            and t.task_id = #{taskId}
        </if>
        order by tur.create_time desc
    </select>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskProvideRecordMapper.xml
New file
@@ -0,0 +1,23 @@
<?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.task.common.dao.TaskProvideRecordMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskProvideRecord">
            <id property="provideRecordId" column="provide_record_id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="type" column="type" jdbcType="INTEGER"/>
            <result property="startTime" column="start_time" jdbcType="VARCHAR"/>
            <result property="endTime" column="end_time" jdbcType="VARCHAR"/>
            <result property="times" column="times" jdbcType="INTEGER"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        provide_record_id,task_id,type,
        start_time,end_time,times,
        create_time,update_time
    </sql>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskProvideUserMapper.xml
New file
@@ -0,0 +1,23 @@
<?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.task.common.dao.TaskProvideUserMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskProvideUser">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="provideRecordId" column="provide_record_id" jdbcType="BIGINT"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
            <result property="dateTime" column="date_time" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="status" column="status" jdbcType="TINYINT"/>
            <result property="process" column="process" jdbcType="VARCHAR"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,provide_record_id,user_id,
        date_time,create_time,task_id,
        status,process
    </sql>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskRateMapper.xml
New file
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.task.common.dao.TaskRateMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskRate">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="liftRatio" column="lift_ratio" jdbcType="TINYINT"/>
            <result property="isStart" column="is_start" jdbcType="TINYINT"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,lift_ratio,
        is_start,create_time
    </sql>
    <select id="listPropAndValue" resultType="com.yami.shop.task.common.model.TaskRate">
        select tr.*,td.task_title from tz_task_rate tr left join (select task_id,task_title from tz_task_detail where task_type = 2)td on tr.task_id = td.task_id
        where 1=1
        <if test="taskRate.taskTitle != null">
            td.task_title like concat('%',#{taskRate.taskTitle},'%')
        </if>
        LIMIT #{adapter.begin}, #{adapter.size}
    </select>
    <select id="countPropAndValue" resultType="java.lang.Long">
        select count(*) from tz_task_rate tr left join (select task_id,task_title from tz_task_detail where task_type = 2)td on tr.task_id = td.task_id
        where 1=1
        <if test="taskRate.taskTitle != null">
            td.task_title like concat('%',#{taskRate.taskTitle},'%')
        </if>
    </select>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskRefreshLogMapper.xml
New file
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.task.common.dao.TaskRefreshLogMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskRefreshLog">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="refreshTime" column="refresh_time" jdbcType="TIMESTAMP"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,refresh_time,
        user_id
    </sql>
    <select id="getTaskRefreshLog" resultType="java.lang.Integer">
        select count(1) from tz_task_refresh_log
                        where user_id = #{userId} and task_id = #{taskId}
    </select>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskRuleMapper.xml
New file
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.task.common.dao.TaskRuleMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskRule">
            <id property="ruleId" column="rule_id" jdbcType="BIGINT"/>
            <result property="ruleName" column="rule_name" jdbcType="VARCHAR"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="taskStatus" column="task_status" jdbcType="TINYINT"/>
            <result property="taskStatusTip" column="task_status_tip" jdbcType="VARCHAR"/>
            <result property="nextStatus" column="next_status" jdbcType="TINYINT"/>
            <result property="targetOpenType" column="target_open_type" jdbcType="VARCHAR"/>
            <result property="targetUrl" column="target_url" jdbcType="VARCHAR"/>
            <result property="ruleCondition" column="rule_condition" jdbcType="VARCHAR"/>
            <result property="valueType" column="value_type" jdbcType="VARCHAR"/>
            <result property="value" column="value" jdbcType="INTEGER"/>
            <result property="enable" column="enable" jdbcType="TINYINT"/>
            <result property="createUserId" column="create_user_id" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        rule_id,rule_name,task_id,
        task_status,task_status_tip,next_status,
        target_open_type,target_url,rule_condition,
        value_type,value,enable,
        create_user_id,create_time
    </sql>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskSignInCommissionMapper.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.task.common.dao.TaskSignInCommissionMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskSignInCommission">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="signInTitle" column="sign_in_title" jdbcType="VARCHAR"/>
            <result property="signInDescription" column="sign_in_description" jdbcType="VARCHAR"/>
            <result property="monCommission" column="mon_commission" jdbcType="BIGINT"/>
            <result property="tueCommission" column="tue_commission" jdbcType="BIGINT"/>
            <result property="wedCommission" column="wed_commission" jdbcType="BIGINT"/>
            <result property="thursCommission" column="thurs_commission" jdbcType="BIGINT"/>
            <result property="friCommission" column="fri_commission" jdbcType="BIGINT"/>
            <result property="satCommission" column="sat_commission" jdbcType="BIGINT"/>
            <result property="sunCommission" column="sun_commission" jdbcType="BIGINT"/>
            <result property="isFinish" column="is_finish" jdbcType="INTEGER"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,mon_commission,
        tue_commission,wed_commission,thurs_commission,
        fri_commission,sat_commission,sun_commission,
        create_time
    </sql>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskSignInLogMapper.xml
New file
@@ -0,0 +1,36 @@
<?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.task.common.dao.TaskSignInLogMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskSignInLog">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
            <result property="money" column="money" jdbcType="BIGINT"/>
            <result property="signInId" column="sign_in_id" jdbcType="BIGINT"/>
            <result property="signInTime" column="sign_in_time" jdbcType="TIMESTAMP"/>
            <result property="isSignIn" column="is_sign_in" jdbcType="TINYINT"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,user_id,sign_in_id,sign_in_time,is_sign_in,create_time,money
    </sql>
    <insert id="insertInitializeSignInLog">
        INSERT INTO tz_task_sign_in_log (id,user_id,sign_in_id,sign_in_time,is_sign_in,create_time,money)
        VALUES
            (null, #{userId}, #{signInId}, DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 0 DAY), '%Y-%m-%d'), 0, NOW(),(select one_day_commission from tz_task_sign_in_commission where id = #{signInId})),
            (null, #{userId}, #{signInId}, DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 1 DAY), '%Y-%m-%d'), 0, NOW(),(select two_day_commission from tz_task_sign_in_commission where id = #{signInId})),
            (null, #{userId}, #{signInId}, DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 2 DAY), '%Y-%m-%d'), 0, NOW(),(select three_day_commission from tz_task_sign_in_commission where id = #{signInId})),
            (null, #{userId}, #{signInId}, DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 3 DAY), '%Y-%m-%d'), 0, NOW(),(select four_day_commission from tz_task_sign_in_commission where id = #{signInId})),
            (null, #{userId}, #{signInId}, DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 4 DAY), '%Y-%m-%d'), 0, NOW(),(select five_day_commission from tz_task_sign_in_commission where id = #{signInId})),
            (null, #{userId}, #{signInId}, DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 5 DAY), '%Y-%m-%d'), 0, NOW(),(select six_day_commission from tz_task_sign_in_commission where id = #{signInId})),
            (null, #{userId}, #{signInId}, DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 6 DAY), '%Y-%m-%d'), 0, NOW(),(select seven_day_commission from tz_task_sign_in_commission where id = #{signInId}));
    </insert>
    <update id="updateByIdAndDate">
        update tz_task_sign_in_log set is_sign_in = 1, sign_in_time = NOW()
                                   where DATE(CURDATE()) = DATE(sign_in_time)
                                    and user_id = #{userId} and sign_in_id = #{signInId}
    </update>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskUserMapper.xml
New file
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yami.shop.task.common.dao.TaskUserMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskUser">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
            <result property="userId" column="user_id" jdbcType="VARCHAR"/>
            <result property="status" column="status" jdbcType="INTEGER"/>
            <result property="remark" column="remark" jdbcType="VARCHAR"/>
            <result property="createUserId" column="create_user_id" jdbcType="INTEGER"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,task_id,user_id,
        status,remark,create_user_id,
        create_time
    </sql>
    <update id="updateTaskStatus">
        update tz_task_user t set t.status =#{status} where t.userId =#{userId} and t.taskId =#{taskId}
    </update>
</mapper>
yami-shop-task/yami-shop-task-common/src/main/resources/mapper/TaskUserRelationMapper.xml
New file
@@ -0,0 +1,17 @@
<?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.task.common.dao.TaskUserRelationMapper">
    <resultMap id="BaseResultMap" type="com.yami.shop.task.common.model.TaskUserRelation">
            <id property="relationId" column="relation_id" jdbcType="BIGINT"/>
            <result property="inviterUserId" column="inviter_user_id" jdbcType="VARCHAR"/>
            <result property="inviteeUserId" column="invitee_user_id" jdbcType="VARCHAR"/>
            <result property="taskId" column="task_id" jdbcType="BIGINT"/>
    </resultMap>
    <sql id="Base_Column_List">
        relation_id,inviter_user_id,invitee_user_id,task_id
    </sql>
</mapper>
yami-shop-task/yami-shop-task-platform/pom.xml
New file
@@ -0,0 +1,33 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.yami.shop</groupId>
        <artifactId>yami-shop-task</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>yami-shop-task-platform</artifactId>
    <description>任务大厅后台管理部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-task-common</artifactId>
            <version>${yami.shop.version}</version>
        </dependency>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-seckill-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-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/config/SwaggerConfiguration.java
New file
@@ -0,0 +1,35 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.task.platform.config;
import lombok.AllArgsConstructor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 任务的swagger文档
 * @author LGH
 */
@Configuration("taskSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi taskRestApi() {
        return GroupedOpenApi.builder()
                .group("任务大厅接口")
                .packagesToScan("com.yami.shop.task.platform.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/controller/TaskController.java
New file
@@ -0,0 +1,137 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.task.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.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.task.common.model.Task;
import com.yami.shop.task.common.model.TaskDetail;
import com.yami.shop.task.common.service.TaskDetailService;
import com.yami.shop.task.common.service.TaskService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
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;
@RestController
@RequestMapping("/platform/task")
@Tag(name = "任务")
public class TaskController {
    @Autowired
    private TaskDetailService taskDetailService;
    @Autowired
    private TaskService taskService;
//    @GetMapping("/page")
    @Operation(summary = "分页获取任务" , description = "分页获取任务")
    public ServerResponseEntity<IPage<TaskDetail>> page(@ParameterObject TaskDetail taskDetail, PageParam<TaskDetail> page){
        IPage<TaskDetail> taskDetailIPage = taskDetailService.page(page,new LambdaQueryWrapper<TaskDetail>()
                .like(StrUtil.isNotBlank(taskDetail.getTaskTitle()), TaskDetail::getTaskTitle,taskDetail.getTaskTitle())
                .like(StrUtil.isNotBlank(taskDetail.getTaskDescription()), TaskDetail::getTaskDescription,taskDetail.getTaskDescription())
                .eq(taskDetail.getIsFinish()!=null, TaskDetail::getIsFinish,taskDetail.getIsFinish())
                .eq(taskDetail.getTaskType()!=null, TaskDetail::getTaskType,taskDetail.getTaskType())
                .eq(taskDetail.getCommissionsType()!=null, TaskDetail::getCommissionsType,taskDetail.getCommissionsType())
                .eq(taskDetail.getAccomplishType()!=null, TaskDetail::getAccomplishType,taskDetail.getAccomplishType())
                .orderByDesc(TaskDetail::getCreateTime)
        );
        return ServerResponseEntity.success(taskDetailIPage);
    }
    @GetMapping("/page")
    @Operation(summary = "分页获取任务" , description = "分页获取任务")
    public ServerResponseEntity<IPage<Task>> taskPage(@ParameterObject Task taskDetail, PageParam<Task> page){
        IPage<Task> taskDetailIPage = taskService.page(page,new LambdaQueryWrapper<Task>()
                .like(StrUtil.isNotBlank(taskDetail.getTaskTitle()), Task::getTaskTitle,taskDetail.getTaskTitle())
                .like(StrUtil.isNotBlank(taskDetail.getTaskDescription()), Task::getTaskDescription,taskDetail.getTaskDescription())
                .eq(taskDetail.getStauts()!=null, Task::getStauts,taskDetail.getStauts())
                .eq(taskDetail.getTaskType()!=null, Task::getTaskType,taskDetail.getTaskType())
                .orderByDesc(Task::getCreateTime)
        );
        return ServerResponseEntity.success(taskDetailIPage);
    }
//    @GetMapping("/info/{id}")
    @Operation(summary = "获取信息" , description = "获取信息")
    @Parameter(name = "id", description = "任务id" )
    public ServerResponseEntity<TaskDetail> info(@PathVariable("id") Long id){
        TaskDetail taskDetail = taskDetailService.getById(id);
        return ServerResponseEntity.success(taskDetail);
    }
    @GetMapping("/info/{id}")
    @Operation(summary = "获取信息" , description = "获取信息")
    @Parameter(name = "id", description = "任务id" )
    public ServerResponseEntity<Task> getInfo(@PathVariable("id") Long id){
        Task taskDetail = taskService.getById(id);
        return ServerResponseEntity.success(taskDetail);
    }
//    @PostMapping
    @Operation(summary = "保存" , description = "保存")
    public ServerResponseEntity<Void> save(@RequestBody @Valid TaskDetail taskDetail){
        taskDetailService.save(taskDetail);
        return ServerResponseEntity.success();
    }
    @PostMapping
    @Operation(summary = "保存" , description = "保存")
    public ServerResponseEntity<Void> add(@RequestBody @Valid Task taskDetail){
        Long userId = SecurityUtils.getSysUser().getUserId();
        taskDetail.setCreateUserId(String.valueOf(userId));
        taskService.save(taskDetail);
        return ServerResponseEntity.success();
    }
//    @PutMapping
    @Operation(summary = "修改" , description = "修改")
    public ServerResponseEntity<Void> update(@RequestBody @Valid TaskDetail taskDetail){
        taskDetailService.updateById(taskDetail);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @Operation(summary = "修改" , description = "修改")
    public ServerResponseEntity<Void> modify(@RequestBody @Valid Task taskDetail){
        Long userId = SecurityUtils.getSysUser().getUserId();
        taskDetail.setUpdateUserId(String.valueOf(userId));
        taskService.updateById(taskDetail);
        return ServerResponseEntity.success();
    }
//    @DeleteMapping
    @Operation(summary = "删除" , description = "删除")
    @Parameter(name = "ids", description = "任务id列表" )
    public ServerResponseEntity<Void> delete(@RequestParam Long id){
        taskDetailService.removeById(id);
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @Operation(summary = "删除" , description = "删除")
    @Parameter(name = "ids", description = "任务id列表" )
    public ServerResponseEntity<Void> remove(@RequestParam Long id){
        taskService.removeById(id);
        return ServerResponseEntity.success();
    }
}
yami-shop-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/controller/TaskRateController.java
New file
@@ -0,0 +1,80 @@
package com.yami.shop.task.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.task.common.model.TaskDetail;
import com.yami.shop.task.common.model.TaskRate;
import com.yami.shop.task.common.service.TaskDetailService;
import com.yami.shop.task.common.service.TaskRateService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
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.List;
@Slf4j
@RestController
@RequestMapping("/platform/taskRate")
@Tag(name = "CDN任务提速配置")
public class TaskRateController {
    @Autowired
    private TaskRateService taskRateService;
    @Autowired
    private TaskDetailService taskDetailService;
    @GetMapping("/page")
    @Operation(summary = "分页获取" , description = "分页获取")
    public ServerResponseEntity<IPage<TaskRate>> page(@ParameterObject TaskRate taskRate, PageParam<TaskRate> page) {
        IPage<TaskRate> list = taskRateService.pagePropAndValue(taskRate, page);
        return ServerResponseEntity.success(list);
    }
    @GetMapping("/list")
    @Operation(summary = "CDN任务列表" , description = "CDN任务列表")
    public ServerResponseEntity<List<TaskDetail>> list(){
        List<TaskDetail> taskDetailIPage = taskDetailService.list(new LambdaQueryWrapper<TaskDetail>()
                .eq(TaskDetail::getTaskType,2)
        );
        return ServerResponseEntity.success(taskDetailIPage);
    }
    @GetMapping("/{id}")
    @Operation(summary = "详情" , description = "详情")
    @Parameter(name = "id", description = "规格id" )
    public ServerResponseEntity<TaskRate> getTaskRateDetail(@PathVariable("id") Long id) {
        TaskRate taskRate = taskRateService.getTaskRateDetail(id);
        return ServerResponseEntity.success(taskRate);
    }
    @PostMapping("/save")
    @Operation(summary = "保存" , description = "保存")
    public ServerResponseEntity<Void> save(@Valid @RequestBody TaskRate taskRate) {
        taskRateService.saveRate(taskRate);
        return ServerResponseEntity.success();
    }
    @PutMapping("/update")
    @Operation(summary = "修改" , description = "修改")
    public ServerResponseEntity<Void> update(@Valid @RequestBody TaskRate taskRate) {
        taskRateService.updateRate(taskRate);
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @Operation(summary = "删除" , description = "删除")
    @Parameter(name = "id", description = "规格id" )
    public ServerResponseEntity<Void> delete(@RequestParam Long id) {
        taskRateService.delete(id);
        return ServerResponseEntity.success();
    }
}
yami-shop-task/yami-shop-task-platform/src/main/java/com/yami/shop/task/platform/controller/TaskReleaseController.java
New file
@@ -0,0 +1,127 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.task.platform.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.model.CdnTeamRelation;
import com.yami.shop.bean.model.User;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.security.platform.util.SecurityUtils;
import com.yami.shop.task.common.model.Task;
import com.yami.shop.task.common.model.TaskDetail;
import com.yami.shop.task.common.model.TaskProvideRecord;
import com.yami.shop.task.common.service.TaskDetailService;
import com.yami.shop.task.common.service.TaskProvideRecordService;
import com.yami.shop.task.common.service.TaskProvideUserService;
import com.yami.shop.task.common.service.TaskService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
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.Date;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/platform/task/release")
@Tag(name = "任务释放")
public class TaskReleaseController {
    @Autowired
    private TaskProvideUserService taskProvideUserService;
    @Autowired
    private TaskProvideRecordService taskProvideRecordService;
    @Autowired
    private TaskService taskService;
    @GetMapping("/page")
    @Operation(summary = "分页获取任务" , description = "分页获取任务")
    public ServerResponseEntity<IPage<TaskProvideRecord>> taskPage(@ParameterObject TaskProvideRecord taskDetail, PageParam<TaskProvideRecord> page){
        LambdaQueryWrapper<TaskProvideRecord> wrapper = new LambdaQueryWrapper<>(TaskProvideRecord.class);
        wrapper.eq(ObjectUtils.isNotNull(taskDetail.getTaskId()), TaskProvideRecord::getTaskId,taskDetail.getTaskId())
                .eq(ObjectUtils.isNotNull(taskDetail.getType()), TaskProvideRecord::getType,taskDetail.getType())
                .orderByDesc(TaskProvideRecord::getCreateTime);
        if (!StrUtil.isBlank(taskDetail.getTaskTitle())) {
            List<Task> tasks = taskService.list(Wrappers.lambdaQuery(Task.class).like(Task::getTaskTitle,taskDetail.getTaskTitle()));
            if (!tasks.isEmpty()) {
                List<Long> taskIds = tasks.stream().map(Task::getTaskId).collect(Collectors.toList());
                if (!taskIds.isEmpty()) {
                    wrapper.in(TaskProvideRecord::getTaskId,taskIds);
                }else {
                    return ServerResponseEntity.success(new PageParam<>());
                }
            } else {
                return ServerResponseEntity.success(new PageParam<>());
            }
        }
        IPage<TaskProvideRecord> taskDetailIPage = taskProvideRecordService.page(page,wrapper);
        if(!taskDetailIPage.getRecords().isEmpty()){
            for (TaskProvideRecord taskProvideRecord : taskDetailIPage.getRecords()){
                Task task = taskService.getById(taskProvideRecord.getTaskId());
                taskProvideRecord.setTaskTitle(task.getTaskTitle());
                taskProvideRecord.setTaskIcon(task.getTaskIcon());
            }
        }
        return ServerResponseEntity.success(taskDetailIPage);
    }
    @GetMapping("/info/{id}")
    @Operation(summary = "获取信息" , description = "获取信息")
    @Parameter(name = "id", description = "任务id" )
    public ServerResponseEntity<TaskProvideRecord> getInfo(@PathVariable("id") Long id){
        TaskProvideRecord taskDetail = taskProvideRecordService.getById(id);
        if(taskDetail != null){
            Task task = taskService.getById(taskDetail.getTaskId());
            taskDetail.setTaskTitle(task.getTaskTitle());
            taskDetail.setTaskIcon(task.getTaskIcon());
        }
        return ServerResponseEntity.success(taskDetail);
    }
    @PostMapping
    @Operation(summary = "保存" , description = "保存")
    public ServerResponseEntity<Void> add(@RequestBody @Valid TaskProvideRecord taskDetail){
        taskDetail.setCreateTime(new Date());
        taskProvideRecordService.save(taskDetail);
        return ServerResponseEntity.success();
    }
    @PutMapping
    @Operation(summary = "修改" , description = "修改")
    public ServerResponseEntity<Void> modify(@RequestBody @Valid TaskProvideRecord taskDetail){
        taskDetail.setUpdateTime(new Date());
        taskProvideRecordService.updateById(taskDetail);
        return ServerResponseEntity.success();
    }
    @DeleteMapping
    @Operation(summary = "删除" , description = "删除")
    @Parameter(name = "ids", description = "任务id列表" )
    public ServerResponseEntity<Void> remove(@RequestParam Long id){
        taskProvideRecordService.removeById(id);
        return ServerResponseEntity.success();
    }
}
yami-shop-user/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-user</artifactId>
    <description>商城会员拓展模块</description>
    <packaging>pom</packaging>
    <modules>
        <module>yami-shop-user-api</module>
        <module>yami-shop-user-multishop</module>
        <module>yami-shop-user-platform</module>
        <module>yami-shop-user-common</module>
    </modules>
</project>
yami-shop-user/yami-shop-user-api/pom.xml
New file
@@ -0,0 +1,34 @@
<?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-user</artifactId>
        <groupId>com.yami.shop</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-user-api</artifactId>
    <description>商城会员拓展模块接口部分</description>
    <dependencies>
        <dependency>
            <groupId>com.yami.shop</groupId>
            <artifactId>yami-shop-user-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-user/yami-shop-user-api/src/main/java/com/yami/shop/user/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.user.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("userSwaggerConfiguration")
@AllArgsConstructor
public class SwaggerConfiguration {
    @Bean
    public GroupedOpenApi scoreMallRestApi() {
        return GroupedOpenApi.builder()
                .group("用户积分和等级接口")
                .packagesToScan("com.yami.shop.user.api.controller")
                .pathsToMatch("/**")
                .build();
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/ScoreOrderController.java
New file
@@ -0,0 +1,167 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.controller;
import com.yami.shop.bean.app.dto.ShopCartDto;
import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.bean.app.param.OrderParam;
import com.yami.shop.bean.enums.DeliveryType;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.vo.UserDeliveryInfoVO;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.CacheManagerUtil;
import com.yami.shop.delivery.api.manager.DeliveryOrderManager;
import com.yami.shop.manager.OrderUseScoreManager;
import com.yami.shop.manager.UserLevelOrderManager;
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.SkuService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.service.ScoreOrderService;
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.List;
import java.util.Objects;
/**
 * @author LHD
 */
@RestController
@AllArgsConstructor
@RequestMapping("/p/score" )
@Tag(name = "积分商品订单接口")
public class ScoreOrderController {
    private final UserExtensionService userExtensionService;
    private final ProductService productService;
    private final ScoreOrderService scoreOrderService;
    private final CacheManagerUtil cacheManagerUtil;
    private final SkuService skuService;
    private final ShopCartAdapter shopCartAdapter;
    private final ShopCartItemAdapter shopCartItemAdapter;
    private final ConfirmOrderManager confirmOrderManager;
    private final DeliveryOrderManager deliveryOrderManager;
    private final UserLevelOrderManager userLevelOrderManager;
    private final OrderUseScoreManager orderUseScoreManager;
    @PostMapping("/confirm")
    @Operation(summary = "结算,生成积分订单信息" , description = "传入下单所需要的参数进行下单")
    public ServerResponseEntity<ShopCartOrderMergerDto> confirm(@Valid @RequestBody OrderParam orderParam) {
        if (Objects.isNull(orderParam.getOrderItem())) {
            // 请选择您需要的商品进行购买
            throw new YamiShopBindException("yami.score.select.num.shop");
        }
        String userId = SecurityUtils.getUser().getUserId();
        // 将要返回给前端的完整的订单信息
        ShopCartOrderMergerDto shopCartOrderMerger = new ShopCartOrderMergerDto();
        shopCartOrderMerger.setDvyType(DeliveryType.EXPRESS.getValue());
        shopCartOrderMerger.setOrderType(OrderType.SCORE);
        shopCartOrderMerger.setMold(0);
        shopCartOrderMerger.setIsScorePay(1);
        shopCartOrderMerger.setPreSellStatus(0);
        List<ShopCartItemDto> shopCartItemsDb = shopCartItemAdapter.getShopCartItem(orderParam.getOrderItem(), null, userId, orderParam.getAddrId());
        // 筛选过滤掉不同配送的商品
        List<ShopCartItemDto> shopCartItems = confirmOrderManager.filterShopItemsByType(shopCartOrderMerger, shopCartItemsDb);
        // 购物车
        List<ShopCartDto> shopCarts = shopCartAdapter.getShopCarts(shopCartItems);
        // 计算运费,获取用户地址,自提信息
        UserDeliveryInfoVO userDeliveryInfo = deliveryOrderManager.calculateAndGetDeliverInfo(userId, orderParam.getAddrId(), orderParam.getDvyType(), shopCartItems);
        // 当算完一遍店铺的各种满减活动时,重算一遍订单金额
        confirmOrderManager.recalculateAmountWhenFinishingCalculateShop(shopCartOrderMerger, shopCarts, userDeliveryInfo);
        double orderShopReduce = shopCartOrderMerger.getOrderReduce();
//        // 等级折扣
//        if (userLevelOrderManager != null) {
//            userLevelOrderManager.calculateLevelDiscount(shopCartOrderMerger);
//        }
//
//        // 结束平台优惠的计算之后,还要重算一遍金额
//        confirmOrderManager.recalculateAmountWhenFinishingCalculatePlatform(shopCartOrderMerger);
//
//        // 计算订单积分抵扣金额
//        if (orderUseScoreManager != null) {
//            orderUseScoreManager.orderUseScore(shopCartOrderMerger, orderParam, shopCartItems);
//        }
        shopCartOrderMerger.setOrderShopReduce(orderShopReduce);
        // 缓存计算
        confirmOrderManager.cacheCalculatedInfo(userId, shopCartOrderMerger);
        return ServerResponseEntity.success(shopCartOrderMerger);
    }
//    /**
//     * 立即购买  提交积分订单
//     */
//    @PostMapping("/submit")
//    @Operation(summary = "提交订单,返回支付流水号" , description = "提交积分订单,用户开始进行支付")
//    public ServerResponseEntity<OrderNumbersDto> submitOrders(@Valid @RequestBody OrderShopParam orderShopParam) {
//        String userId = SecurityUtils.getUser().getUserId();
//
//        // 防止重复、同时提交
//        boolean cad = RedisUtil.cad(OrderCacheNames.SCORE_ORDER_CONFIRM_UUID_KEY + OrderCacheNames.UNION  + userId, userId);
//        System.out.println(" is cad " + cad);
//        if (!cad) {
//            // 订单状态已经发生改变,请重新下单
//            throw new YamiShopBindException("yami.order.status.check.change");
//        }
//
//        // 看看订单的标记有没有过期
//        if (cacheManagerUtil.getCache(OrderCacheNames.SCORE_ORDER_CONFIRM_KEY,  userId) == null) {
//            // 订单已过期,请重新下单
//            throw new YamiShopBindException("yami.order.expired");
//        }
//
//        ScoreOrderMergerDto mergerOrder = cacheManagerUtil.getCache(OrderCacheNames.SCORE_ORDER_CONFIRM_KEY, userId);
//        if (mergerOrder == null) {
//            // 订单已过期,请重新下单
//            throw new YamiShopBindException("yami.order.expired");
//        }
//
//        UserExtension user = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId,userId));
//        if(user.getScore() == null){
//            user.setScore(0);
//        }
//        ProductItemDto productItemDto = mergerOrder.getProductItemDto();
//        if(productItemDto.getScorePrice() > user.getScore()) {
//            // 用户积分不足
//            throw new YamiShopBindException("yami.user.score.enough");
//        }
//        StringBuilder orderNumbers = new StringBuilder();
//        mergerOrder.setRemarks(orderShopParam.getRemarks());
//        Order scoreOrder = scoreOrderService.submit(userId,mergerOrder);
//        orderNumbers.append(scoreOrder.getOrderNumber());
//        // 移除缓存
//        skuService.removeSkuCacheBySkuId(mergerOrder.getProductItemDto().getSkuId(),mergerOrder.getProductItemDto().getProdId());
//        productService.removeProdCacheByProdId(mergerOrder.getProductItemDto().getProdId());
//
//        scoreOrderService.removeConfirmScoreOrderCache(userId);
//        return ServerResponseEntity.success(new OrderNumbersDto(orderNumbers.toString()));
//    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserBalanceController.java
New file
@@ -0,0 +1,75 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.dto.UserBalanceDto;
import com.yami.shop.user.common.model.UserBalance;
import com.yami.shop.user.common.service.UserBalanceService;
import io.swagger.v3.oas.annotations.tags.Tag;
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.RestController;
import java.util.List;
import java.util.Objects;
/**
 * 余额充值级别表
 *
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
@RestController
@AllArgsConstructor
@Tag(name = "会员充值信息接口")
@RequestMapping("/p/userBalance" )
public class UserBalanceController {
    private final UserBalanceService userBalanceService;
    private final UserExtensionService userExtensionService;
    private final MapperFacade mapperFacade;
    /**
     * 查询充值数据列表
     * @return 列表数据
     */
    @GetMapping("/getList" )
    @Operation(summary = "获取充值数据列表" , description = "获取充值数据列表")
    public ServerResponseEntity<List<UserBalanceDto>> getUserBalancePage() {
        List<UserBalance> balanceList = userBalanceService.getBalanceList();
        List<UserBalanceDto> userBalanceDtoList = mapperFacade.mapAsList(balanceList, UserBalanceDto.class);
        return ServerResponseEntity.success(userBalanceDtoList);
    }
    /**
     * 查询用户余额
     * @return 用户余额
     */
    @GetMapping("/getBalanceInfo" )
    @Operation(summary = "查询用户余额" , description = "查询用户余额")
    public ServerResponseEntity<Double> getBalanceInfo() {
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, SecurityUtils.getUser().getUserId()));
        Double balance = userExtension.getTotalBalance();
        if (Objects.isNull(balance)){
            balance = 0.0;
        }
        return ServerResponseEntity.success(balance);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserBalanceLogController.java
New file
@@ -0,0 +1,55 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.security.api.util.SecurityUtils;
import com.yami.shop.user.common.dto.UserBalanceLogDto;
import com.yami.shop.user.common.service.UserBalanceLogService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * 余额充值记录
 *
 * @author YXF
 * @date 2020-09-09 17:38:30
 */
@RestController
@AllArgsConstructor
@Tag(name = "用户余额记录接口")
@RequestMapping("/p/userBalanceLog" )
public class UserBalanceLogController {
    private final UserBalanceLogService userBalanceLogService;
    /**
     * 分页查询用户余额记录
     * @param page 分页对象
     * @return 分页数据
     */
    @GetMapping("/log" )
    @Operation(summary = "查询用户余额记录" , description = "分页查询用户余额记录")
    public ServerResponseEntity<IPage<UserBalanceLogDto>> getUserBalanceLogPage(PageParam<UserBalanceLogDto> page) {
        String userId = SecurityUtils.getUser().getUserId();
        IPage<UserBalanceLogDto> userBalanceLogPage = userBalanceLogService.getLogPage(page, userId);
        return ServerResponseEntity.success(userBalanceLogPage);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserLevelController.java
New file
@@ -0,0 +1,112 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.service.UserService;
import com.yami.shop.user.common.dto.LevelDetailDto;
import com.yami.shop.user.common.dto.LevelDto;
import com.yami.shop.user.common.service.UserLevelService;
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.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 会员等级
 *
 * @author LHD
 * @date 2019-12-19 10:27:46
 */
@RestController
@AllArgsConstructor
@RequestMapping("/p/score/scoreLevel" )
@Tag(name = "会员等级接口")
public class UserLevelController {
    private final UserLevelService levelService;
    private final UserService userService;
    private final UserExtensionService userExtensionService;
    /**
     * 获取会员等级信息页信息
     */
    @GetMapping("/page" )
    @Operation(summary = "会员等级信息" , description = "会员等级信息")
    @Parameter(name = "levelType", description = "会员等级类型0为根据会员自身情况 1为付费" , required = true)
    public ServerResponseEntity<LevelDto> getScoreLogPage(Integer levelType) {
        String userId = SecurityUtils.getUser().getUserId();
        User user = userService.getById(userId);
        UserExtension extension = userExtensionService.getOne(
                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, userId));
        if(levelType == 0){
            levelType = extension.getLevelType() == null ? 0:extension.getLevelType();
        }else{
            levelType = 1;
        }
        List<LevelDetailDto> userLevels = levelService.selectLevelAndRights(levelType);
        LevelDetailDto nowLevel = new LevelDetailDto();
        LevelDetailDto nextLevel = new LevelDetailDto();
        //通过用户积分获取当前等级和下一等级
        for (LevelDetailDto userLevel : userLevels) {
            if (extension.getLevel() >= userLevel.getLevel()) {
                nowLevel = userLevel;
            } else {
                nextLevel = userLevel;
                break;
            }
        }
        LevelDto userLevelDto = new LevelDto();
        userLevelDto.setNickName(user.getNickName());
        userLevelDto.setEndTime(user.getVipEndTime());
        userLevelDto.setScore(extension.getScore());
        userLevelDto.setGrowth(extension.getGrowth());
        userLevelDto.setNeedGrowth(nowLevel.getNeedGrowth());
        userLevelDto.setUserLevel(nowLevel);
        userLevelDto.setLevelType(nowLevel.getLevelType());
        userLevelDto.setLevelName(nowLevel.getLevelName());
        userLevelDto.setNextGrowth(nextLevel.getNeedGrowth() == null ?nextLevel.getNeedGrowth():nextLevel.getNeedGrowth());
        userLevelDto.setNextLevelName(nextLevel.getLevelName() == null ?nowLevel.getLevelName():nextLevel.getLevelName());
        userLevelDto.setUserLevels(userLevels);
        return ServerResponseEntity.success(userLevelDto);
    }
    /**
     * 返回金额最低的会员价格和年限
     */
    @GetMapping("/minAmountLevel" )
    @Operation(summary = "返回金额最低的会员价格和年限" , description = "返回金额最低的会员价格和年限")
    public ServerResponseEntity<LevelDetailDto> getScoreLogPage() {
        List<LevelDetailDto> userLevels = levelService.selectLevelAndRights(1);
        //返回 先以金额升序 期数降序
        List<LevelDetailDto> levelDetailDtos = userLevels.stream().sorted(
                Comparator.comparing(LevelDetailDto::getNeedAmount).thenComparing(LevelDetailDto::getTermType, Comparator.reverseOrder())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(levelDetailDtos)){
            return ServerResponseEntity.success();
        }
        return ServerResponseEntity.success(levelDetailDtos.get(0));
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/controller/UserScoreController.java
New file
@@ -0,0 +1,224 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.controller;
import cn.hutool.core.date.DateUtil;
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.ScoreLogType;
import com.yami.shop.bean.event.UpdateUserScoreEvent;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.ScoreConfigParam;
import com.yami.shop.bean.param.ScoreExpireParam;
import com.yami.shop.common.bean.SysConfig;
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.common.util.PageParam;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.SysConfigService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.dto.ScoreDataDto;
import com.yami.shop.user.common.model.UserLevel;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserLevelService;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * 积分中心接口
 *
 * @author LHD
 * @date 2019-3-18 10:27:46
 */
@RestController
@RequestMapping("/p/score")
@Tag(name = "积分中心接口")
@AllArgsConstructor
public class UserScoreController {
    private final UserScoreLogService scoreLogService;
    private final UserScoreDetailService userScoreDetailService;
    private final ApplicationContext applicationContext;
    private final SysConfigService sysConfigService;
    private final UserExtensionService userExtensionService;
    private final UserLevelService userLevelService;
    @GetMapping("/updateUserScore")
    @Operation(summary = "积分签到" , description = "积分签到")
    public ServerResponseEntity<String> updateUserScore() {
        String userId = SecurityUtils.getUser().getUserId();
        UserExtension extension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, userId));
        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
        //签到,计算连续签到日期
        if (isSignIn(userId, DateUtil.date())) {
            // 今天已经签到过了,请明天再试!
            return ServerResponseEntity.success(I18nMessage.getMessage("yami.user.receive.score.check"));
        }
        //根据逗号分隔
        String[] signInScore = scoreParam.getSignInScoreString().split(StrUtil.COMMA);
        int count = Math.min(extension.getSignDay(), signInScore.length - 1);
        long score = Long.parseLong(signInScore[count]);
        int signDay;
        // 查询昨天有没有签到,没有则初始化为1
        if (isSignIn(userId, DateUtil.offsetDay(DateUtil.date(), -1))) {
            signDay = extension.getSignDay() + 1;
        } else {
            signDay = 1;
        }
        String remarks = "签到第" + count + "天获取的积分";
        applicationContext.publishEvent(new UpdateUserScoreEvent(ScoreLogType.SIGN_IN.value(), score, 1,
                null, remarks, userId,signDay));
        // 领取积分成功
        return ServerResponseEntity.success(I18nMessage.getMessage("yami.user.receive.score"));
    }
    @GetMapping("/scoreInfo")
    @Operation(summary = "查看积分中心信息" , description = "查看积分中心信息")
    public ServerResponseEntity<ScoreDataDto> scoreInfo() {
        ScoreDataDto scoreDataDto = new ScoreDataDto();
        String userId = SecurityUtils.getUser().getUserId();
        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
        // 0.计算过期时间
        ScoreExpireParam scoreExpireParam = sysConfigService.getSysConfigObject(Constant.SCORE_EXPIRE, ScoreExpireParam.class);
        if (Objects.isNull(scoreParam)) {
            return ServerResponseEntity.success();
        }
        Integer year = Objects.isNull(scoreExpireParam) ? 0 : scoreExpireParam.getExpireYear();
        ArrayList<Integer> signInScores = new ArrayList<>();
        for (String s : scoreParam.getSignInScoreString().trim().split(StrUtil.COMMA)) {
            Integer signInScore = Integer.valueOf(s);
            signInScores.add(signInScore);
        }
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, userId));
        if (userExtension == null) {
            return ServerResponseEntity.success();
        }
        // 查询连续签到天数不大于0并且没有连续签到初始化为0
        boolean isContinuousSign = !isSignIn(userId,DateUtil.offsetDay(DateUtil.date(),-1)) && !isSignIn(userId,DateUtil.date())
                && (Objects.isNull(userExtension.getSignDay()) || userExtension.getSignDay() != 0);
        if(isContinuousSign) {
            userExtension.setSignDay(0);
            userExtensionService.updateById(userExtension);
        }
        UserScoreDetail userScoreDetail = userScoreDetailService.getOne(new LambdaQueryWrapper<UserScoreDetail>().eq(UserScoreDetail::getUserId, userId)
                .eq(UserScoreDetail::getStatus, -1).orderByDesc(UserScoreDetail::getExpireTime).last("limit 1"));
        scoreDataDto.setIsRegister(1);
        scoreDataDto.setExpireScore(Objects.nonNull(userScoreDetail) ? userScoreDetail.getUsableScore() : 0L);
        scoreDataDto.setExpireYear(year);
        scoreDataDto.setScoreExpireSwitch(scoreExpireParam.getScoreExpireSwitch());
        scoreDataDto.setGrowth(userExtension.getGrowth());
        scoreDataDto.setScore(userExtension.getScore());
        scoreDataDto.setScoreList(signInScores);
        scoreDataDto.setRegisterScore(scoreParam.getRegisterScore());
        scoreDataDto.setShopScore(scoreParam.getShopGetScore());
        scoreDataDto.setIsSignIn(isSignIn(userId, DateUtil.date()) ? 1 : 0);
        scoreDataDto.setLevelType(userExtension.getLevelType());
        UserLevel userLevel = userLevelService.getOne(new LambdaQueryWrapper<UserLevel>()
                .eq(UserLevel::getLevel, userExtension.getLevel())
                .eq(UserLevel::getLevelType, userExtension.getLevelType())
        );
        scoreDataDto.setLevelName(userLevel.getLevelName());
        //计算签到天数
        int count = userExtension.getSignDay() <= 0 ? 1 : userExtension.getSignDay();
        // 如果不为第一天签到或者大于等于第七天的签到,+1
        if (userExtension.getSignDay() != 0 && !isSignIn(userId, DateUtil.date())) {
            count++;
        }
        scoreDataDto.setSignInCount(count);
        return ServerResponseEntity.success(scoreDataDto);
    }
    /**
     * 是否已经签到
     *
     * @param userId
     * @param date
     * @return
     */
    private boolean isSignIn(String userId, Date date) {
        List<UserScoreLog> scoreList = scoreLogService.list(new LambdaQueryWrapper<UserScoreLog>().eq(UserScoreLog::getSource, ScoreLogType.SIGN_IN.value())
                .ge(UserScoreLog::getCreateTime, DateUtil.beginOfDay(date))
                .le(UserScoreLog::getCreateTime, DateUtil.endOfDay(date))
                .eq(UserScoreLog::getUserId, userId));
        return CollectionUtils.isNotEmpty(scoreList);
    }
    /**
     * 分页查询积分明细
     *
     * @param page 分页对象
     * @return 分页数据
     */
    @GetMapping("/page")
    @Operation(summary = "查询积分明细" , description = "查询积分明细")
    public ServerResponseEntity<IPage<UserScoreLog>> getScoreLogPage(PageParam<UserScoreLog> page) {
        String userId = SecurityUtils.getUser().getUserId();
        return ServerResponseEntity.success(scoreLogService.getPageByUserId(page, userId));
    }
    /**
     * 等级页展示
     *
     * @return 等级页展示
     */
    @GetMapping("/getLevelShow")
    @Operation(summary = "等级页展示" , description = "等级页展示")
    public ServerResponseEntity<String> getLevelShow() {
        String config = sysConfigService.getSysConfigObject(Constant.LEVEL_SHOW, String.class);
        if (Objects.isNull(config)) {
            return ServerResponseEntity.success();
        }
        return ServerResponseEntity.success(config);
    }
    /**
     * 积分常见问题
     *
     * @return 积分常见问题
     */
    @GetMapping("/getScoreQuestion")
    @Operation(summary = "积分常见问题" , description = "积分常见问题")
    public ServerResponseEntity<SysConfig> getScoreQuestion() {
        SysConfig config = sysConfigService.getOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getParamKey, Constant.SCORE_QUESTION));
        if (Objects.isNull(config)) {
            return ServerResponseEntity.success(new SysConfig());
        }
        return ServerResponseEntity.success(config);
    }
    @GetMapping("/getExpiringScore")
    @Operation(summary = "获取用户年底将要过期积分总数" , description = "获取用户年底将要过期积分总数")
    public ServerResponseEntity<Long> getExpiringScore() {
        String userId = SecurityUtils.getUser().getUserId();
        Long expiringScore = userScoreDetailService.getExpiringScoreByUserId(userId);
        return ServerResponseEntity.success(expiringScore);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BalancePayListener.java
New file
@@ -0,0 +1,127 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.app.param.PayInfoParam;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.enums.PayEntry;
import com.yami.shop.bean.enums.PayStatus;
import com.yami.shop.bean.enums.UserBalanceLogType;
import com.yami.shop.bean.event.BalancePayEvent;
import com.yami.shop.bean.model.CdnFlow;
import com.yami.shop.bean.model.CdnUserWallet;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.WalletEnum;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Arith;
import com.yami.shop.service.*;
import com.yami.shop.user.common.model.UserBalanceLog;
import com.yami.shop.user.common.service.UserBalanceLogService;
import com.yami.shop.user.common.service.UserLevelService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * 余额支付操作
 *
 * @author lhd
 */
@Component("balanceListener")
@AllArgsConstructor
public class BalancePayListener {
    private final PayInfoService payInfoService;
    private final CdnUserWalletService cdnUserWalletService;
    private final CdnFlowService cdnFlowService;
    private final CdnConfigService cdnConfigService;
    @EventListener(BalancePayEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void balanceListener(BalancePayEvent event) {
        PayInfoDto payInfoDTO = event.getPayInfo();
        PayInfoParam payInfoParam = event.getPayInfoParam();
        PayInfo payInfo = payInfoService.getOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, payInfoDTO.getPayNo()));
        BigDecimal amount = BigDecimal.valueOf(payInfo.getPayAmount());
        // 已经支付
        if (Objects.equals(payInfo.getPayStatus(), PayStatus.PAYED.value()) || Objects.equals(payInfo.getPayStatus(), PayStatus.REFUND.value())) {
            return;
        }
        CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, WalletEnum.BALANCE.value()));
        if (Objects.isNull(cdnUserWallet)) {
            payInfoParam.setType(2);
            // 您的信息有误,请尝试刷新后再进行操作
            payInfoParam.setMessage(I18nMessage.getMessage("yami.information.is.wrong"));
            return;
        }
        Double balancePayServiceDouble = Double.parseDouble(cdnConfigService.selectValueByName("balance_pay_service"));
        BigDecimal balancePayServiceRadio = BigDecimal.valueOf(balancePayServiceDouble);
        BigDecimal oldmoney = cdnUserWallet.getMoney();
        BigDecimal balancePayService = amount.multiply(balancePayServiceRadio);
        if(Objects.isNull(cdnUserWallet.getMoney()) || cdnUserWallet.getMoney().compareTo(amount.add(balancePayService)) < 0) {
            payInfoParam.setType(3);
            // 您的余额不足,请先充值余额
            payInfoParam.setMessage(I18nMessage.getMessage("yami.balance.is.insufficient"));
            return;
        }
        cdnUserWallet.setMoney(cdnUserWallet.getMoney().subtract(amount).subtract(balancePayService));
        cdnUserWallet.setUpdateTime(new Date());
        cdnUserWalletService.updateById(cdnUserWallet);
        // 订单金额大于0,则添加余额记录
        if(amount.compareTo(BigDecimal.ZERO) > 0) {
            CdnFlow cdnFlow = new CdnFlow();
            cdnFlow.setUserId(payInfo.getUserId());
            cdnFlow.setFlownameId(5); // 购买产品
            cdnFlow.setWalletId(WalletEnum.BALANCE.value()); // 瓜瓜豆支付
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setMoney(amount.negate());
            cdnFlow.setMemo("余额购买产品");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setDate(new Date());
            cdnFlowService.save(cdnFlow);
            cdnFlow.setMoney(balancePayService.negate());
            cdnFlow.setMemo("余额购买产品扣除手续费");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlowService.save(cdnFlow);
        }
        PayInfoResultBO payInfoResultBO = new PayInfoResultBO();
        payInfoResultBO.setIsPaySuccess(true);
        payInfoResultBO.setPayNo(payInfo.getPayNo());
        payInfoResultBO.setCallbackContent("余额支付成功");
        payInfoResultBO.setPayAmount(payInfo.getPayAmount());
        payInfoResultBO.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO, payInfo);
        }
        payInfoParam.setType(1);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BeanPayListener.java
New file
@@ -0,0 +1,110 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.PayInfoParam;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.enums.PayEntry;
import com.yami.shop.bean.enums.PayStatus;
import com.yami.shop.bean.event.BeanPayEvent;
import com.yami.shop.bean.model.CdnFlow;
import com.yami.shop.bean.model.CdnUserWallet;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.WalletEnum;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.service.CdnConfigService;
import com.yami.shop.service.CdnFlowService;
import com.yami.shop.service.CdnUserWalletService;
import com.yami.shop.service.PayInfoService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
/**
 * 余额支付操作
 *
 * @author lhd
 */
@Component("beanListener")
@AllArgsConstructor
public class BeanPayListener {
    private final PayInfoService payInfoService;
    private final CdnUserWalletService cdnUserWalletService;
    private final CdnFlowService cdnFlowService;
    private final CdnConfigService cdnConfigService;
    @EventListener(BeanPayEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void beanListener(BeanPayEvent event) {
        PayInfoDto payInfoDTO = event.getPayInfo();
        PayInfoParam payInfoParam = event.getPayInfoParam();
        PayInfo payInfo = payInfoService.getOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, payInfoDTO.getPayNo()));
        BigDecimal amount = BigDecimal.valueOf(payInfo.getPayAmount());
        // 已经支付
        if (Objects.equals(payInfo.getPayStatus(), PayStatus.PAYED.value()) || Objects.equals(payInfo.getPayStatus(), PayStatus.REFUND.value())) {
            return;
        }
        CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, WalletEnum.BEAN.value()));
        if (Objects.isNull(cdnUserWallet)) {
            payInfoParam.setType(2);
            // 您的信息有误,请尝试刷新后再进行操作
            payInfoParam.setMessage(I18nMessage.getMessage("yami.information.is.wrong"));
            return;
        }
        BigDecimal oldmoney = cdnUserWallet.getMoney();
        if(Objects.isNull(cdnUserWallet.getMoney()) || cdnUserWallet.getMoney().compareTo(amount) < 0) {
            payInfoParam.setType(3);
            // 您的余额不足,请先充值余额
            payInfoParam.setMessage(I18nMessage.getMessage("yami.balance.is.insufficient"));
            return;
        }
        cdnUserWallet.setUpdateTime(new Date());
        cdnUserWallet.setMoney(cdnUserWallet.getMoney().subtract(amount));
        cdnUserWalletService.updateById(cdnUserWallet);
        // 订单金额大于0,则添加余额记录
        if(amount.compareTo(BigDecimal.ZERO) > 0) {
            CdnFlow cdnFlow = new CdnFlow();
            cdnFlow.setUserId(payInfo.getUserId());
            cdnFlow.setFlownameId(5); // 购买产品
            cdnFlow.setWalletId(WalletEnum.BEAN.value()); // 瓜瓜豆支付
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setMoney(amount.negate());
            cdnFlow.setMemo("瓜瓜豆购买产品");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setDate(new Date());
            cdnFlowService.save(cdnFlow);
        }
        PayInfoResultBO payInfoResultBO = new PayInfoResultBO();
        payInfoResultBO.setIsPaySuccess(true);
        payInfoResultBO.setPayNo(payInfo.getPayNo());
        payInfoResultBO.setCallbackContent("瓜瓜豆支付成功");
        payInfoResultBO.setPayAmount(payInfo.getPayAmount());
        payInfoResultBO.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO, payInfo);
        }
        payInfoParam.setType(1);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BlueBalancePayListener.java
New file
@@ -0,0 +1,143 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.PayInfoParam;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.enums.PayEntry;
import com.yami.shop.bean.enums.PayStatus;
import com.yami.shop.bean.event.BlueBalancePayEvent;
import com.yami.shop.bean.model.CdnFlow;
import com.yami.shop.bean.model.CdnUserWallet;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.WalletEnum;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.service.CdnConfigService;
import com.yami.shop.service.CdnFlowService;
import com.yami.shop.service.CdnUserWalletService;
import com.yami.shop.service.PayInfoService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Objects;
/**
 * 红积分支付操作
 *
 * @author lhd
 */
@Component("blueBalancePayListener")
@AllArgsConstructor
public class BlueBalancePayListener {
    private final PayInfoService payInfoService;
    private final CdnUserWalletService cdnUserWalletService;
    private final CdnFlowService cdnFlowService;
    private final CdnConfigService cdnConfigService;
    @EventListener(BlueBalancePayEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void balanceListener(BlueBalancePayEvent event) {
        PayInfoDto payInfoDTO = event.getPayInfo();
        PayInfoParam payInfoParam = event.getPayInfoParam();
        PayInfo payInfo = payInfoService.getOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, payInfoDTO.getPayNo()));
        BigDecimal amount = BigDecimal.valueOf(payInfo.getPayAmount());
        // 已经支付
        if (Objects.equals(payInfo.getPayStatus(), PayStatus.PAYED.value()) || Objects.equals(payInfo.getPayStatus(), PayStatus.REFUND.value())) {
            return;
        }
        CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, Integer.valueOf(WalletEnum.BALANCE.value())));
        CdnUserWallet cdnUserblueWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, Integer.valueOf(WalletEnum.BLUEPOINT.value())));
        if (Objects.isNull(cdnUserWallet)) {
            payInfoParam.setType(2);
            // 您的信息有误,请尝试刷新后再进行操作
            payInfoParam.setMessage(I18nMessage.getMessage("yami.information.is.wrong"));
            return;
        }
        //组合支付 获取红积分+蓝积分比例
        String balanceConfig = cdnConfigService.selectValueByName("blue_match_balance_ratio");
        BigDecimal balanceRatio = new BigDecimal(payInfo.getPayAmount()).multiply(new BigDecimal(balanceConfig))
                .setScale(2, RoundingMode.HALF_UP);
        BigDecimal blueRatio = new BigDecimal(payInfo.getPayAmount()).subtract(balanceRatio);
        BigDecimal oldmoney = cdnUserWallet.getMoney();
        cdnUserWallet.setMoney(cdnUserWallet.getMoney().subtract(balanceRatio));
        cdnUserWallet.setUpdateTime(new Date());
        cdnUserWalletService.updateById(cdnUserWallet);
        BigDecimal oldBluemoney = cdnUserblueWallet.getMoney();
        cdnUserblueWallet.setMoney(cdnUserblueWallet.getMoney().subtract(blueRatio));
        cdnUserblueWallet.setUpdateTime(new Date());
        cdnUserWalletService.updateById(cdnUserblueWallet);
        // 订单金额大于0,则添加流水记录
        if(amount.compareTo(BigDecimal.ZERO) > 0) {
            //增加红积分流水
            CdnFlow cdnFlow = new CdnFlow();
            cdnFlow.setUserId(payInfo.getUserId());
            cdnFlow.setFlownameId(5); // 购买产品
            cdnFlow.setWalletId(WalletEnum.REDPOINT.value()); // 红积分支付
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setMoney(balanceRatio.negate());
            cdnFlow.setMemo("余额购买商城商品");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setDate(new Date());
            cdnFlowService.save(cdnFlow);
            //增加蓝积分流水
            cdnFlow.setWalletId(WalletEnum.BLUEPOINT.value()); // 红积分支付
            cdnFlow.setMoney(blueRatio.negate());
            cdnFlow.setMemo("蓝积分购买商城商品");
            cdnFlow.setOldmoney(oldBluemoney);
            cdnFlowService.save(cdnFlow);
//            cdnFlow.setMoney(balancePayService.negate());
//            cdnFlow.setMemo("余额购买产品扣除手续费");
//            cdnFlow.setOldmoney(oldmoney.subtract(balancePayService));
//            cdnFlowService.save(cdnFlow);
        }
        //红积分订单回调
        PayInfoResultBO payInfoResultBO = new PayInfoResultBO();
        payInfoResultBO.setIsPaySuccess(true);
        payInfoResultBO.setPayNo(payInfo.getPayNo());
        payInfoResultBO.setCallbackContent("余额支付成功");
        payInfoResultBO.setPayAmount(Double.parseDouble(String.valueOf(balanceRatio)));
        payInfoResultBO.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO, payInfo);
        }
        //蓝积分订单回调
        PayInfoResultBO payInfoResultBO1 = new PayInfoResultBO();
        payInfoResultBO1.setIsPaySuccess(true);
        payInfoResultBO1.setPayNo(payInfo.getPayNo());
        payInfoResultBO1.setCallbackContent("蓝积分支付成功");
        payInfoResultBO1.setPayAmount(Double.parseDouble(String.valueOf(blueRatio)));
        payInfoResultBO1.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO1, payInfo);
        }
        payInfoParam.setType(1);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BluePointPayListener.java
New file
@@ -0,0 +1,119 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.PayInfoParam;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.enums.PayEntry;
import com.yami.shop.bean.enums.PayStatus;
import com.yami.shop.bean.event.BluePointPayEvent;
import com.yami.shop.bean.model.CdnFlow;
import com.yami.shop.bean.model.CdnUserWallet;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.WalletEnum;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.service.CdnConfigService;
import com.yami.shop.service.CdnFlowService;
import com.yami.shop.service.CdnUserWalletService;
import com.yami.shop.service.PayInfoService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
/**
 * 余额支付操作
 *
 * @author lhd
 */
@Component("bluePointListener")
@AllArgsConstructor
public class BluePointPayListener {
    private final PayInfoService payInfoService;
    private final CdnUserWalletService cdnUserWalletService;
    private final CdnFlowService cdnFlowService;
    private final CdnConfigService cdnConfigService;
    @EventListener(BluePointPayEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void balanceListener(BluePointPayEvent event) {
        PayInfoDto payInfoDTO = event.getPayInfo();
        PayInfoParam payInfoParam = event.getPayInfoParam();
        PayInfo payInfo = payInfoService.getOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, payInfoDTO.getPayNo()));
        BigDecimal amount = BigDecimal.valueOf(payInfo.getPayAmount());
        // 已经支付
        if (Objects.equals(payInfo.getPayStatus(), PayStatus.PAYED.value()) || Objects.equals(payInfo.getPayStatus(), PayStatus.REFUND.value())) {
            return;
        }
        CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, WalletEnum.BLUEPOINT.value()));
        if (Objects.isNull(cdnUserWallet)) {
            payInfoParam.setType(2);
            // 您的信息有误,请尝试刷新后再进行操作
            payInfoParam.setMessage(I18nMessage.getMessage("yami.information.is.wrong"));
            return;
        }
        Double bluePointPayServiceDouble = Double.parseDouble(cdnConfigService.selectValueByName("blue_point_pay_service"));
        BigDecimal bluePointServiceRadio = BigDecimal.valueOf(bluePointPayServiceDouble);
        BigDecimal oldmoney = cdnUserWallet.getMoney();
        BigDecimal bluePointPayService = amount.multiply(bluePointServiceRadio);
        if(Objects.isNull(cdnUserWallet.getMoney()) || cdnUserWallet.getMoney().compareTo(amount.add(bluePointPayService)) < 0) {
            payInfoParam.setType(3);
            // 您的余额不足,请先充值余额
            payInfoParam.setMessage(I18nMessage.getMessage("yami.balance.is.insufficient"));
            return;
        }
        cdnUserWallet.setMoney(cdnUserWallet.getMoney().subtract(amount).subtract(bluePointPayService));
        cdnUserWallet.setUpdateTime(new Date());
        cdnUserWalletService.updateById(cdnUserWallet);
        // 订单金额大于0,则添加余额记录
        if(amount.compareTo(BigDecimal.ZERO) > 0) {
            CdnFlow cdnFlow = new CdnFlow();
            cdnFlow.setUserId(payInfo.getUserId());
            cdnFlow.setFlownameId(5); // 购买产品
            cdnFlow.setWalletId(WalletEnum.BLUEPOINT.value()); // 瓜瓜豆支付
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setMoney(amount.negate());
            cdnFlow.setMemo("蓝积分购买产品");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setDate(new Date());
            cdnFlowService.save(cdnFlow);
            cdnFlow.setMoney(bluePointPayService.negate());
            cdnFlow.setMemo("蓝积分购买产品扣除手续费");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlowService.save(cdnFlow);
        }
        PayInfoResultBO payInfoResultBO = new PayInfoResultBO();
        payInfoResultBO.setIsPaySuccess(true);
        payInfoResultBO.setPayNo(payInfo.getPayNo());
        payInfoResultBO.setCallbackContent("蓝积分支付成功");
        payInfoResultBO.setPayAmount(payInfo.getPayAmount());
        payInfoResultBO.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO, payInfo);
        }
        payInfoParam.setType(1);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/BlueRedPayListener.java
New file
@@ -0,0 +1,143 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.PayInfoParam;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.enums.PayEntry;
import com.yami.shop.bean.enums.PayStatus;
import com.yami.shop.bean.event.BlueRedPayEvent;
import com.yami.shop.bean.model.CdnFlow;
import com.yami.shop.bean.model.CdnUserWallet;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.WalletEnum;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.service.CdnConfigService;
import com.yami.shop.service.CdnFlowService;
import com.yami.shop.service.CdnUserWalletService;
import com.yami.shop.service.PayInfoService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Objects;
/**
 * 红积分支付操作
 *
 * @author lhd
 */
@Component("blueRedPayListener")
@AllArgsConstructor
public class BlueRedPayListener {
    private final PayInfoService payInfoService;
    private final CdnUserWalletService cdnUserWalletService;
    private final CdnFlowService cdnFlowService;
    private final CdnConfigService cdnConfigService;
    @EventListener(BlueRedPayEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void balanceListener(BlueRedPayEvent event) {
        PayInfoDto payInfoDTO = event.getPayInfo();
        PayInfoParam payInfoParam = event.getPayInfoParam();
        PayInfo payInfo = payInfoService.getOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, payInfoDTO.getPayNo()));
        BigDecimal amount = BigDecimal.valueOf(payInfo.getPayAmount());
        // 已经支付
        if (Objects.equals(payInfo.getPayStatus(), PayStatus.PAYED.value()) || Objects.equals(payInfo.getPayStatus(), PayStatus.REFUND.value())) {
            return;
        }
        CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, Integer.valueOf(WalletEnum.REDPOINT.value())));
        CdnUserWallet cdnUserblueWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, Integer.valueOf(WalletEnum.BLUEPOINT.value())));
        if (Objects.isNull(cdnUserWallet)) {
            payInfoParam.setType(2);
            // 您的信息有误,请尝试刷新后再进行操作
            payInfoParam.setMessage(I18nMessage.getMessage("yami.information.is.wrong"));
            return;
        }
        //组合支付 获取红积分+蓝积分比例
        String redConfig  = cdnConfigService.selectValueByName("blue_match_red_ratio");
        BigDecimal redRatio = new BigDecimal(payInfo.getPayAmount()).multiply(new BigDecimal(redConfig))
                .setScale(2, RoundingMode.HALF_UP);
        BigDecimal blueRatio = new BigDecimal(payInfo.getPayAmount()).subtract(redRatio);
        BigDecimal oldmoney = cdnUserWallet.getMoney();
        cdnUserWallet.setMoney(cdnUserWallet.getMoney().subtract(redRatio));
        cdnUserWallet.setUpdateTime(new Date());
        cdnUserWalletService.updateById(cdnUserWallet);
        BigDecimal oldBluemoney = cdnUserblueWallet.getMoney();
        cdnUserblueWallet.setMoney(cdnUserblueWallet.getMoney().subtract(blueRatio));
        cdnUserblueWallet.setUpdateTime(new Date());
        cdnUserWalletService.updateById(cdnUserblueWallet);
        // 订单金额大于0,则添加流水记录
        if(amount.compareTo(BigDecimal.ZERO) > 0) {
            //增加红积分流水
            CdnFlow cdnFlow = new CdnFlow();
            cdnFlow.setUserId(payInfo.getUserId());
            cdnFlow.setFlownameId(5); // 购买产品
            cdnFlow.setWalletId(WalletEnum.REDPOINT.value()); // 红积分支付
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setMoney(redRatio.negate());
            cdnFlow.setMemo("红积分购买商城商品");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setDate(new Date());
            cdnFlowService.save(cdnFlow);
            //增加蓝积分流水
            cdnFlow.setWalletId(WalletEnum.BLUEPOINT.value()); // 红积分支付
            cdnFlow.setMoney(blueRatio.negate());
            cdnFlow.setMemo("蓝积分购买商城商品");
            cdnFlow.setOldmoney(oldBluemoney);
            cdnFlowService.save(cdnFlow);
//            cdnFlow.setMoney(balancePayService.negate());
//            cdnFlow.setMemo("余额购买产品扣除手续费");
//            cdnFlow.setOldmoney(oldmoney.subtract(balancePayService));
//            cdnFlowService.save(cdnFlow);
        }
        //红积分订单回调
        PayInfoResultBO payInfoResultBO = new PayInfoResultBO();
        payInfoResultBO.setIsPaySuccess(true);
        payInfoResultBO.setPayNo(payInfo.getPayNo());
        payInfoResultBO.setCallbackContent("红积分支付成功");
        payInfoResultBO.setPayAmount(Double.parseDouble(String.valueOf(redRatio)));
        payInfoResultBO.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO, payInfo);
        }
        //蓝积分订单回调
        PayInfoResultBO payInfoResultBO1 = new PayInfoResultBO();
        payInfoResultBO1.setIsPaySuccess(true);
        payInfoResultBO1.setPayNo(payInfo.getPayNo());
        payInfoResultBO1.setCallbackContent("蓝积分支付成功");
        payInfoResultBO1.setPayAmount(Double.parseDouble(String.valueOf(blueRatio)));
        payInfoResultBO1.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO1, payInfo);
        }
        payInfoParam.setType(1);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/LevelUpListener.java
New file
@@ -0,0 +1,83 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.ScoreLogType;
import com.yami.shop.bean.event.LevelUpEvent;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.ScoreConfigParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.service.SysConfigService;
import com.yami.shop.user.common.model.UserLevel;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserLevelService;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
/**
 * 用户等级提升操作
 *
 * @author lhd
 */
@Component("levelUpListener")
@AllArgsConstructor
public class LevelUpListener {
    private final UserLevelService userLevelService;
    private final SysConfigService sysConfigService;
    private final UserScoreDetailService userScoreDetailService;
    private final UserScoreLogService userScoreLogService;
    /**
     * 用户等级提升操作
     */
    @EventListener(LevelUpEvent.class)
    public void levelUpListener(LevelUpEvent event) {
        UserLevel userLevel = userLevelService.getOne(
                new LambdaQueryWrapper<UserLevel>().eq(UserLevel::getLevel, 1).eq(UserLevel::getLevelType, 0));
        ArrayList<UserLevel> userLevels = new ArrayList<>();
        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
        userLevels.add(userLevel);
        UserExtension userExtension = event.getUserExtension();
        Integer beforeLevel = userExtension.getLevel();
        if(scoreParam != null && scoreParam.getRegisterScore() != null) {
            userExtension.setScore(scoreParam.getRegisterScore());
            //添加积分明细
            UserScoreDetail addDetail = new UserScoreDetail();
            addDetail.setCreateTime(new Date());
            addDetail.setStatus(1);
            addDetail.setUserId(userExtension.getUserId());
            addDetail.setUsableScore(scoreParam.getRegisterScore());
            userScoreDetailService.saveUserScoreDetail(addDetail);
            //添加积分日志
            UserScoreLog userScoreLog = new UserScoreLog();
            userScoreLog.setUserId(userExtension.getUserId());
            userScoreLog.setScore(scoreParam.getRegisterScore());
            userScoreLog.setSource(ScoreLogType.REGISTER.value());
            userScoreLog.setCreateTime(new Date());
            userScoreLog.setIoType(1);
            userScoreLogService.save(userScoreLog);
        }
        userLevelService.levelUp(userLevels,null,userExtension,null,beforeLevel);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/RedPayListener.java
New file
@@ -0,0 +1,119 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.param.PayInfoParam;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.enums.PayEntry;
import com.yami.shop.bean.enums.PayStatus;
import com.yami.shop.bean.event.RedPayEvent;
import com.yami.shop.bean.model.CdnFlow;
import com.yami.shop.bean.model.CdnUserWallet;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.pay.PayInfoDto;
import com.yami.shop.common.enums.WalletEnum;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.service.CdnConfigService;
import com.yami.shop.service.CdnFlowService;
import com.yami.shop.service.CdnUserWalletService;
import com.yami.shop.service.PayInfoService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
/**
 * 红积分支付操作
 *
 * @author lhd
 */
@Component("redPayListener")
@AllArgsConstructor
public class RedPayListener {
    private final PayInfoService payInfoService;
    private final CdnUserWalletService cdnUserWalletService;
    private final CdnFlowService cdnFlowService;
    private final CdnConfigService cdnConfigService;
    @EventListener(RedPayEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void balanceListener(RedPayEvent event) {
        PayInfoDto payInfoDTO = event.getPayInfo();
        PayInfoParam payInfoParam = event.getPayInfoParam();
        PayInfo payInfo = payInfoService.getOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, payInfoDTO.getPayNo()));
        BigDecimal amount = BigDecimal.valueOf(payInfo.getPayAmount());
        // 已经支付
        if (Objects.equals(payInfo.getPayStatus(), PayStatus.PAYED.value()) || Objects.equals(payInfo.getPayStatus(), PayStatus.REFUND.value())) {
            return;
        }
        CdnUserWallet cdnUserWallet = cdnUserWalletService.getOne(new LambdaQueryWrapper<CdnUserWallet>()
                .eq(CdnUserWallet::getUserId, payInfo.getUserId())
                .eq(CdnUserWallet::getWalletId, Integer.valueOf(WalletEnum.REDPOINT.value())));
        if (Objects.isNull(cdnUserWallet)) {
            payInfoParam.setType(2);
            // 您的信息有误,请尝试刷新后再进行操作
            payInfoParam.setMessage(I18nMessage.getMessage("yami.information.is.wrong"));
            return;
        }
//        Double balancePayServiceDouble = Double.parseDouble(cdnConfigService.selectValueByName("balance_pay_service"));
//        BigDecimal balancePayServiceRadio = BigDecimal.valueOf(balancePayServiceDouble);
//
//        BigDecimal balancePayService = amount.multiply(balancePayServiceRadio);
//        if(Objects.isNull(cdnUserWallet.getMoney()) || cdnUserWallet.getMoney().compareTo(amount.add(balancePayService)) < 0) {
//            payInfoParam.setType(3);
//            // 您的余额不足,请先充值余额
//            payInfoParam.setMessage(I18nMessage.getMessage("yami.balance.is.insufficient"));
//            return;
//        }
        BigDecimal oldmoney = cdnUserWallet.getMoney();
        cdnUserWallet.setMoney(cdnUserWallet.getMoney().subtract(amount));
        cdnUserWallet.setUpdateTime(new Date());
        cdnUserWalletService.updateById(cdnUserWallet);
        // 订单金额大于0,则添加余额记录
        if(amount.compareTo(BigDecimal.ZERO) > 0) {
            CdnFlow cdnFlow = new CdnFlow();
            cdnFlow.setUserId(payInfo.getUserId());
            cdnFlow.setFlownameId(5); // 购买产品
            cdnFlow.setWalletId(WalletEnum.REDPOINT.value()); // 红积分支付
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setMoney(amount.negate());
            cdnFlow.setMemo("红积分购买商城商品");
            cdnFlow.setOldmoney(oldmoney);
            cdnFlow.setCreateTime(new Date());
            cdnFlow.setDate(new Date());
            cdnFlowService.save(cdnFlow);
//            cdnFlow.setMoney(balancePayService.negate());
//            cdnFlow.setMemo("余额购买产品扣除手续费");
//            cdnFlow.setOldmoney(oldmoney.subtract(balancePayService));
//            cdnFlowService.save(cdnFlow);
        }
        PayInfoResultBO payInfoResultBO = new PayInfoResultBO();
        payInfoResultBO.setIsPaySuccess(true);
        payInfoResultBO.setPayNo(payInfo.getPayNo());
        payInfoResultBO.setCallbackContent("红积分支付成功");
        payInfoResultBO.setPayAmount(payInfo.getPayAmount());
        payInfoResultBO.setBizPayNo(payInfo.getPayNo());
        if (Objects.equals(payInfo.getPayEntry(), PayEntry.ORDER.value())) {
            // 订单支付回调
            payInfoService.noticeOrder(payInfoResultBO, payInfo);
        }
        payInfoParam.setType(1);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/SubmitOrderListener.java
New file
@@ -0,0 +1,123 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.bean.enums.ScoreLogType;
import com.yami.shop.bean.event.SubmitScoreOrderEvent;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.order.SubmitOrderOrder;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import lombok.AllArgsConstructor;
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.Date;
import java.util.List;
/**
 * 确认订单信息时的用户积分操作
 *
 * @author LGH
 */
@Component("userSubmitOrderListener")
@AllArgsConstructor
public class SubmitOrderListener {
    private final UserExtensionService userExtensionService;
    private final UserScoreDetailService userScoreDetailService;
    private final UserScoreLogService userScoreLogService;
    /**
     * 计算订单金额
     */
    @EventListener(SubmitScoreOrderEvent.class)
    @Order(SubmitOrderOrder.USER)
    public void userSubmitOrderListener(SubmitScoreOrderEvent event) {
        ShopCartOrderMergerDto mergerOrder = event.getMergerOrder();
        if(mergerOrder.getIsScorePay() == 0 || mergerOrder.getTotalUsableScore() <= 0){
            return;
        }
        Date now = new Date();
        String userId = SecurityUtils.getUser().getUserId();
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, userId));
        //查询积分详细表数据
        List<UserScoreDetail> scoreDetailList = userScoreDetailService.list(new LambdaQueryWrapper<UserScoreDetail>()
                .eq(UserScoreDetail::getUserId, userExtension.getUserId()).eq(UserScoreDetail::getStatus,1).orderByAsc(UserScoreDetail::getCreateTime));
        if(CollectionUtils.isEmpty(scoreDetailList)){
            // 积分不足无法提交订单
            throw new YamiShopBindException("yami.user.score.no.enough");
        }
        long score = scoreDetailList.stream().mapToLong(UserScoreDetail::getUsableScore).sum();
        if(userExtension.getScore() < mergerOrder.getTotalUsableScore() || score < mergerOrder.getTotalUsableScore()){
            // 积分不足无法提交订单
            throw new YamiShopBindException("yami.user.score.no.enough");
        }
        //添加积分日志
        List<com.yami.shop.bean.model.Order> orders = event.getOrders();
        List<UserScoreLog> logList = new ArrayList<>();
        List<UserScoreDetail> updateScoreDetails = new ArrayList<>();
        for (com.yami.shop.bean.model.Order order : orders) {
            long updateScore = order.getScore();
            UserScoreLog userScoreLog = new UserScoreLog();
            userScoreLog.setUserId(userId);
            userScoreLog.setBizId(order.getOrderNumber());
            userScoreLog.setScore(order.getScore());
            userScoreLog.setSource(ScoreLogType.SCORE_CASH.value());
            userScoreLog.setCreateTime(now);
            userScoreLog.setIoType(0);
            logList.add(userScoreLog);
            // 修改积分明细,如果当前明细不够扣除在进行下一条
            // 如果够添加一条积分明细记录
            for (UserScoreDetail scoreDetail : scoreDetailList) {
                if(scoreDetail.getUsableScore() <= updateScore){
                    scoreDetail.setStatus(0);
                    scoreDetail.setBizId(order.getOrderNumber());
                    updateScoreDetails.add(scoreDetail);
                    updateScore -= scoreDetail.getUsableScore();
                }else{
                    UserScoreDetail addDetail = new UserScoreDetail();
                    addDetail.setCreateTime(scoreDetail.getCreateTime());
                    addDetail.setStatus(0);
                    addDetail.setUserId(scoreDetail.getUserId());
                    addDetail.setBizId(order.getOrderNumber());
                    addDetail.setUsableScore(updateScore);
                    userScoreDetailService.save(addDetail);
                    scoreDetail.setUsableScore(scoreDetail.getUsableScore() - updateScore);
                    updateScoreDetails.add(scoreDetail);
                    break;
                }
                if(updateScore <= 0){
                    break;
                }
            }
        }
        userScoreLogService.saveBatch(logList);
        userScoreDetailService.updateBatchById(updateScoreDetails);
        //保存用户积分
        userExtension.setScore(userExtension.getScore() - mergerOrder.getTotalUsableScore());
        userExtensionService.updateById(userExtension);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/listener/UpdateUserScoreListener.java
New file
@@ -0,0 +1,79 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.api.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.event.UpdateUserScoreEvent;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.order.ConfirmOrderOrder;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
 *  用户领取积分接口
 *
 * @author LHD
 * @date 2019/12/17
 **/
@Component("updateUserScoreListener")
@AllArgsConstructor
public class UpdateUserScoreListener {
    private final UserScoreLogService scoreLogService;
    private final UserExtensionService userExtensionService;
    private final UserScoreDetailService userScoreDetailService;
    /**
     *  根据领取方式的不同添加用户积分及日志
     */
    @EventListener(UpdateUserScoreEvent.class)
    @Order(ConfirmOrderOrder.DEFAULT)
    public void receiveScoreListener(UpdateUserScoreEvent event) {
        UserExtension extension = userExtensionService.getOne(
                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, event.getUserId()));
        Integer consumeType = event.getConsumeType();
        if(event.getScore() == null){
            return;
        }
        Long score = event.getScore();
        UserScoreLog scoreLog = new UserScoreLog();
        scoreLog.setSource(consumeType);
        scoreLog.setCreateTime(new Date());
        scoreLog.setIoType(event.getIoType());
        //添加一条日志和修改用户积分
        scoreLog.setUserId(extension.getUserId());
        scoreLog.setScore(score);
        scoreLogService.save(scoreLog);
        if(event.getIoType() == 1){
            extension.setScore(extension.getScore() + score);
            // 添加积分明细
            UserScoreDetail addDetail = new UserScoreDetail();
            addDetail.setCreateTime(new Date());
            addDetail.setStatus(1);
            addDetail.setUserId(extension.getUserId());
            addDetail.setUsableScore(score);
            userScoreDetailService.saveUserScoreDetail(addDetail);
        }else{
            extension.setScore(extension.getScore() - score);
        }
        extension.setSignDay(event.getSignDay());
        userExtensionService.updateById(extension);
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/manager/impl/OrderUseScoreManagerImpl.java
New file
@@ -0,0 +1,302 @@
package com.yami.shop.user.api.manager.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.dto.ShopCartItemDiscountDto;
import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.app.dto.ShopCartOrderDto;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.bean.app.param.OrderParam;
import com.yami.shop.bean.model.Category;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.ScoreConfigParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.util.Arith;
import com.yami.shop.manager.OrderUseScoreManager;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.CategoryService;
import com.yami.shop.service.SysConfigService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.util.CategoryScale;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * @author FrozenWatermelon
 * @date 2021/12/23
 */
@Component
@AllArgsConstructor
public class OrderUseScoreManagerImpl implements OrderUseScoreManager {
    private final UserExtensionService userExtensionService;
    private final SysConfigService sysConfigService;
    private final CategoryService categoryService;
    private static final Integer SCORE_RATIO = 100;
    private static final Integer MIN_SCORE_RATIO = 10;
    @Override
    public void orderUseScore(ShopCartOrderMergerDto shopCartOrderMergerDto, OrderParam orderParam, List<ShopCartItemDto> allCartItem) {
//        // 如果是预售订单则不能使用优惠
//        if (Objects.equals(orderParam.getPreSellStatus(), 1)) {
//            return;
//        }
        // 获取用户等级积分详细表
        UserExtension extension = userExtensionService.getOne(
                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, SecurityUtils.getUser().getUserId()));
        // 获取配置信息
        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
        if (Objects.nonNull(scoreParam) && scoreParam.getShopScoreSwitch() != null && !scoreParam.getShopScoreSwitch()) {
            return;
        }
        if (orderParam.getUserUseScore() != null && orderParam.getUserUseScore() < 0 && extension.getScore() < 0) {
            return;
        }
        // 最大可抵现金额 = ((订单实际金额 - 订单最小金额) * 使用积分分类比例上限)
        double totalActualAmount = Arith.sub(shopCartOrderMergerDto.getActualTotal(), shopCartOrderMergerDto.getTotalTransFee());
        // 计算积分最多抵现金额
        double totalScoreAmount = 0.0;
        List<Category> categories = categoryService.listByShopId(Constant.PLATFORM_SHOP_ID);
        Map<Long, Double> categoryMap = CategoryScale.getScaleByCategory(categories, scoreParam, 0);
        double useDiscount = Objects.isNull(scoreParam.getUseDiscount()) ? 0.0 : scoreParam.getUseDiscount();
        // 单积分抵扣金额
        double scoreDeductionAmount = Arith.div(1, scoreParam.getShopUseScore(), 2);
        // 积分抵现金额可用上限 = 订单可使用积分比例 * ((实际总值)/100)
        if (scoreParam.getUseDiscountRange() == 0) {
            // 如果有等级优惠金额,还需减去等级的优惠金额、运费才是实际金额,包邮时运费为0
            double actualTotal = Arith.add(Arith.sub(shopCartOrderMergerDto.getActualTotal(), shopCartOrderMergerDto.getTotalTransFee()), shopCartOrderMergerDto.getFreeTransFee());
            double notScoreAmount =0.0;
            // 获取大类的比例并转成map
            for (ShopCartItemDto shopCartItem : allCartItem) {
                if (shopCartItem.getActualTotal() < scoreDeductionAmount) {
                    notScoreAmount = Arith.add(notScoreAmount,shopCartItem.getActualTotal());
                }
            }
            actualTotal = Arith.sub(actualTotal , notScoreAmount);
            totalScoreAmount = Arith.div(Arith.mul(actualTotal, useDiscount), 100);
        } else {
            // 获取大类的比例并转成map
            for (ShopCartItemDto shopCartItem : allCartItem) {
                if (!categoryMap.containsKey(shopCartItem.getCategoryId())) {
                    continue;
                }
                if(shopCartItem.getActualTotal() < scoreDeductionAmount){
                    continue;
                }
                // 商品总额减去总优惠,就是商品项的实际金额
                double actualTotal = Arith.sub(shopCartItem.getProductTotalAmount(), shopCartItem.getShareReduce());
                double scoreReduce = Arith.div(Arith.mul(actualTotal, categoryMap.get(shopCartItem.getCategoryId())), 100);
                totalScoreAmount = Arith.add(totalScoreAmount, scoreReduce);
            }
        }
        calculatedScoreAmount(extension, totalActualAmount, shopCartOrderMergerDto, scoreParam, categoryMap, totalScoreAmount, orderParam);
    }
    /**
     * 计算可用的积分及积分抵扣金额
     * @param extension
     * @param totalActualAmount
     * @param shopCartOrderMergerDto
     * @param scoreParam
     * @param categoryMap
     * @param totalScoreAmount
     * @param orderParam
     */
    private void calculatedScoreAmount(UserExtension extension, double totalActualAmount, ShopCartOrderMergerDto shopCartOrderMergerDto, ScoreConfigParam scoreParam,
                                  Map<Long, Double> categoryMap, double totalScoreAmount, OrderParam orderParam) {
        // 计算用户可用积分 如果大于总共的积分使用比例直接使用,如果小于根据比例使用
        int canUseScore = (int) Arith.mul(totalScoreAmount, scoreParam.getShopUseScore());
        Long userUseScore = extension.getScore();
        Long totalUsableScore = extension.getScore();
        //如果是用户选择的积分数额,则用此积分数额
        if (orderParam.getUserUseScore() != null && orderParam.getIsScorePay() == 1 && orderParam.getUserUseScore() >= 0) {
            userUseScore = Math.min(orderParam.getUserUseScore(), userUseScore);
        } else {
            userUseScore = 0L;
        }
        long maxScore = Math.min(totalUsableScore, canUseScore);
        userUseScore = Math.min(userUseScore, canUseScore);
        // 如果为大于100的比例,则积分需要整10使用
        if (scoreParam.getShopUseScore() > SCORE_RATIO) {
            userUseScore = userUseScore - userUseScore % MIN_SCORE_RATIO;
            maxScore = maxScore - maxScore % MIN_SCORE_RATIO;
        }
        // 计算可抵扣金额,然后算使用积分,然后再用使用积分算抵扣金额
        totalScoreAmount = Arith.div(userUseScore, scoreParam.getShopUseScore(), 2);
        userUseScore = (long) Arith.mul(totalScoreAmount, scoreParam.getShopUseScore());
        totalScoreAmount = Arith.div(userUseScore, scoreParam.getShopUseScore(), 2);
        // 在极端积分比例的情况下,最大可用积分和使用的积分有冲突操作
        double maxScoreAmount = Arith.div(maxScore, scoreParam.getShopUseScore(), 2);
        maxScore = (long) Arith.mul(maxScoreAmount, scoreParam.getShopUseScore());
        double scale = 1.0;
        // 这里如果不使用最大可用积分,则后续的计算还需要乘以这个比例 - 积分抵扣比例 = 积分抵扣金额/订单实际金额
        if (userUseScore < canUseScore) {
            scale = Arith.div(Arith.div(userUseScore, scoreParam.getShopUseScore()), totalActualAmount);
        }
        // 用户选择积分抵现,组装积分信息
        List<ShopCartOrderDto> shopCartOrders = shopCartOrderMergerDto.getShopCartOrders();
        double totalScoreReduce = 0.0;
        double useDiscount = Objects.isNull(scoreParam.getUseDiscount()) ? 0.0 : scoreParam.getUseDiscount();
        long totalScore = 0;
        calculatedAmount(shopCartOrderMergerDto, scoreParam, categoryMap, totalScoreAmount, orderParam, canUseScore, userUseScore, maxScore, scale, shopCartOrders, totalScoreReduce, useDiscount, totalScore);
    }
    /**
     * 计算商品的积分抵扣金额
     * @param shopCartOrderMergerDto
     * @param scoreParam
     * @param categoryMap
     * @param totalScoreAmount
     * @param orderParam
     * @param canUseScore
     * @param userUseScore
     * @param maxScore
     * @param scale
     * @param shopCartOrders
     * @param totalScoreReduce
     * @param useDiscount
     * @param totalScore
     */
    private void calculatedAmount(ShopCartOrderMergerDto shopCartOrderMergerDto, ScoreConfigParam scoreParam, Map<Long, Double> categoryMap, double totalScoreAmount, OrderParam orderParam, int canUseScore, Long userUseScore, long maxScore, double scale, List<ShopCartOrderDto> shopCartOrders, double totalScoreReduce, double useDiscount, long totalScore) {
        // 通过for i找出最后一项,将计算偏差的1积分给最后的最大的一项
        double maxAmount = 0.0;
        Long maxAmountSkuId = 0L;
        for (ShopCartOrderDto shopCartOrderDto : shopCartOrders) {
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrderDto.getShopCartItemDiscounts()) {
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    maxAmountSkuId = shopCartItem.getActualTotal() > maxAmount ? shopCartItem.getSkuId() : maxAmountSkuId;
                    maxAmount = Math.max(shopCartItem.getActualTotal(),maxAmount);
                }
            }
        }
        for (int shopIndex = 0; shopIndex < shopCartOrders.size(); shopIndex++) {
            ShopCartOrderDto shopCartOrder = shopCartOrders.get(shopIndex);
            double reduceSum = 0.0;
            long shopScore = 0;
            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts();
            for (int discountIndex = 0; discountIndex < shopCartItemDiscounts.size(); discountIndex++) {
                List<ShopCartItemDto> shopCartItems = shopCartItemDiscounts.get(discountIndex).getShopCartItems();
                for (int itemIndex = 0; itemIndex < shopCartItems.size(); itemIndex++) {
                    ShopCartItemDto shopCartItem = shopCartItems.get(itemIndex);
                    // 如果是金额最大的一项,直接跳过,最后在处理
                    if(Objects.equals(shopCartItem.getSkuId(),maxAmountSkuId)){
                        continue;
                    }
                    double scoreReduceProd = 0.0;
                    double actualTotal = 0.0;
                    // 计算商品可以用于积分抵扣的金额
                    if (userUseScore < canUseScore) {
                        // 部分积分抵扣, 需要计算商品分摊积分的比例
                        actualTotal = Arith.roundByBanker(Arith.mul(shopCartItem.getActualTotal(), scale), 2);
                    } else {
                        // 全部积分抵扣
                        actualTotal = shopCartItem.getActualTotal();
                    }
                    // 计算商品分摊的金额,需要乘以比例
                    if (scoreParam.getUseDiscountRange() == 0) {
                        scoreReduceProd = Arith.div(Arith.mul(actualTotal, useDiscount), 100, 2);
                    } else if (categoryMap.containsKey(shopCartItem.getCategoryId())) {
                        scoreReduceProd = Arith.div(Arith.mul(actualTotal, categoryMap.get(shopCartItem.getCategoryId())), 100, 2);
                    }
                    // 计算该商品的最大抵扣积分数量
                    long useScore = (long) Arith.roundByBanker(Arith.mul(scoreReduceProd, scoreParam.getShopUseScore()), 0);
                    scoreReduceProd = Arith.div(useScore, scoreParam.getShopUseScore(), 2);
                    // 如果大于可用上限则直接等于,接将剩余的抵扣金额全部赋予最后一个,积分和金额直接等于 使用的 - 已经抵扣的
                    if (Arith.add(totalScoreReduce, scoreReduceProd) > totalScoreAmount) {
                        // 减去当前总共的积分,减去店铺已分摊的积分
                        useScore = userUseScore - totalScore - shopScore;
                        scoreReduceProd = Arith.sub(totalScoreAmount, totalScoreReduce);
                    }
                    totalScoreReduce = Arith.add(totalScoreReduce, scoreReduceProd);
                    reduceSum = Arith.add(reduceSum, scoreReduceProd);
                    shopScore += useScore;
                    if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
                        double platformReduce = shopCartItem.getPlatformShareReduce() == null ? 0 : shopCartItem.getPlatformShareReduce();
                        shopCartItem.setPlatformShareReduce(Arith.add(platformReduce, scoreReduceProd));
                        shopCartItem.setScorePayReduce(scoreReduceProd);
                        shopCartItem.setScorePrice(useScore);
                        shopCartItem.setShareReduce(Arith.add(Arith.roundByBanker(shopCartItem.getShareReduce(), 2), scoreReduceProd));
                        shopCartItem.setActualTotal(Arith.sub(shopCartItem.getActualTotal(), scoreReduceProd));
                    }
                }
            }
            // 设置店铺的实际总值、积分优惠金额和订单优惠金额
            shopCartOrder.setScoreReduce(reduceSum);
            shopCartOrder.setActualTotal(Arith.sub(shopCartOrder.getActualTotal(), reduceSum));
            // 放入优惠金额
            shopCartOrder.setShopReduce(Arith.add(shopCartOrder.getShopReduce(), reduceSum));
            // 放入平台优惠金额,如果用户等级免自营店运费也要放进去
            shopCartOrder.setPlatformAmount(Arith.add(shopCartOrder.getPlatformAmount(), reduceSum));
            totalScore += shopScore;
            if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
                shopCartOrder.setUseScore(shopScore);
            }
        }
        // 处理最后一项
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    // 如果不是金额最大的一项,直接跳过
                    if (!Objects.equals(shopCartItem.getSkuId(), maxAmountSkuId)) {
                        continue;
                    }
                    // 减去当前总共的积分,减去店铺已分摊的积分
                    long useScore = userUseScore - totalScore;
                    double scoreReduceProd = Arith.sub(totalScoreAmount, totalScoreReduce);
                    if(scoreReduceProd > shopCartItem.getActualTotal()) {
                        scoreReduceProd = Math.min(scoreReduceProd, shopCartItem.getActualTotal());
                        useScore = (long) Arith.mul(Arith.roundByBanker(Arith.mul(scoreReduceProd, scale), 2), scoreParam.getShopUseScore());
                        scoreReduceProd = Arith.div(useScore, scoreParam.getShopUseScore(), 2);
                    }
                    // 用计算出的积分抵扣金额跟商品实际金额进行比较,如果积分抵扣金额大于商品实际金额就不进行积分抵扣处理了,防止订单金额小于0
                    if (shopCartItem.getActualTotal() < scoreReduceProd) {
                        continue;
                    }
                    if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
                        double platformReduce = shopCartItem.getPlatformShareReduce() == null ? 0 : shopCartItem.getPlatformShareReduce();
                        shopCartItem.setPlatformShareReduce(Arith.add(platformReduce, scoreReduceProd));
                        shopCartItem.setScorePayReduce(scoreReduceProd);
                        shopCartItem.setScorePrice(useScore);
                        shopCartItem.setShareReduce(Arith.add(Arith.roundByBanker(shopCartItem.getShareReduce(), 2), scoreReduceProd));
                        shopCartItem.setActualTotal(Arith.sub(shopCartItem.getActualTotal(), scoreReduceProd));
                    }
                    // 设置店铺的实际总值、积分优惠金额和订单优惠金额
                    shopCartOrder.setScoreReduce(Arith.add(shopCartOrder.getScoreReduce(),scoreReduceProd));
                    shopCartOrder.setActualTotal(Arith.sub(shopCartOrder.getActualTotal(), scoreReduceProd));
                    // 放入优惠金额
                    shopCartOrder.setShopReduce(Arith.add(shopCartOrder.getShopReduce(), scoreReduceProd));
                    // 放入平台优惠金额,如果用户等级免自营店运费也要放进去
                    shopCartOrder.setPlatformAmount(Arith.add(shopCartOrder.getPlatformAmount(), scoreReduceProd));
                    if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
                        shopCartOrder.setUseScore(shopCartOrder.getUseScore() + useScore);
                    }
                    totalScoreReduce = Arith.add(totalScoreReduce, scoreReduceProd);
                    totalScore += useScore;
                    break;
                }
            }
        }
        // 设置订单的实际总值和订单优惠金额
        shopCartOrderMergerDto.setTotalScoreAmount(totalScoreReduce);
        shopCartOrderMergerDto.setShopUseScore(scoreParam.getShopUseScore());
        shopCartOrderMergerDto.setTotalUsableScore(totalScore);
        shopCartOrderMergerDto.setActualTotal(Arith.sub(shopCartOrderMergerDto.getActualTotal(), totalScoreReduce));
        shopCartOrderMergerDto.setOrderReduce(Arith.add(shopCartOrderMergerDto.getOrderReduce(), totalScoreReduce));
        shopCartOrderMergerDto.setMaxUsableScore(maxScore);
        if (orderParam.getIsScorePay() != null && orderParam.getIsScorePay() == 1) {
            shopCartOrderMergerDto.setScorePrice(totalScore);
        }
    }
}
yami-shop-user/yami-shop-user-api/src/main/java/com/yami/shop/user/api/manager/impl/UserLevelOrderManagerImpl.java
New file
@@ -0,0 +1,180 @@
package com.yami.shop.user.api.manager.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.app.dto.ShopCartItemDiscountDto;
import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.app.dto.ShopCartOrderDto;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.bean.enums.OrderActivityType;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.util.Arith;
import com.yami.shop.manager.UserLevelOrderManager;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.dao.UserLevelMapper;
import com.yami.shop.user.common.model.UserLevel;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author FrozenWatermelon
 * @date 2021/12/21
 */
@Component
public class UserLevelOrderManagerImpl implements UserLevelOrderManager {
    @Autowired
    private UserLevelMapper userLevelMapper;
    @Autowired
    private UserExtensionService userExtensionService;
    private Long maxAmountSkuId;
    @Override
    public void calculateLevelDiscount(ShopCartOrderMergerDto shopCartOrderMerger) {
//        // 如果是预售订单则不能使用优惠
//        if (Objects.equals(shopCartOrderMerger.getPreSellStatus(), 1)) {
//            return;
//        }
        UserExtension extension = userExtensionService.getOne(
                new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, SecurityUtils.getUser().getUserId()));
        if (Objects.isNull(extension)) {
            return;
        }
        if (extension.getLevel() == null) {
            extension.setLevel(Constant.USER_LEVEL_INIT);
        }
        UserLevel level = userLevelMapper.selectOneAndCategory(extension);
        if (Objects.isNull(level) || level.getDiscount() > Constant.MAX_LEVEL_DISCOUNT) {
            return;
        }
        List<ShopCartOrderDto> shopCartOrders = shopCartOrderMerger.getShopCartOrders();
        // 获取分类比例
        // 最后计算成长值折扣
        double levelDiscount = 0.0;
        double freeTransFee = 0.0;
        double discount = Arith.sub(10, level.getDiscount());
        List<Long> categoryIds = level.getCategoryIds();
        Set<Long> categorySet = new HashSet<>(categoryIds);
        List<ShopCartItemDto> shopCartItems = new ArrayList<>();
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            // 店铺中的满减项列表
            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                // 如果是套餐活动跳过循环
                if (Objects.equals(shopCartItemDiscount.getActivityType(), OrderActivityType.COMBO.value())) {
                    continue;
                }
                shopCartItems.addAll(shopCartItemDiscount.getShopCartItems());
            }
        }
        // 计算折扣总额
        double maxLevelFeeTotal = getLevelFeeTotal(shopCartItems, level, categorySet);
        // 通过for i找出最后一项,将计算偏差的金额给最后的最大的一项
        for (int shopIndex = 0; shopIndex < shopCartOrders.size(); shopIndex++) {
            ShopCartOrderDto shopCartOrder = shopCartOrders.get(shopIndex);
            // 如果可用范围为自营店不为当前店铺直接下一次循环
            if (level.getDiscountRange() == 1 && !Objects.equals(shopCartOrder.getShopId(), 1L)) {
                continue;
            }
            double reduceSum = 0.0;
//            boolean isShopEnd = shopIndex == shopCartOrders.size() - 1;
            for (int index = 0; index < shopCartItems.size(); index++) {
                ShopCartItemDto shopCartItem = shopCartItems.get(index);
                if (!Objects.equals(shopCartItem.getShopId(), shopCartOrder.getShopId())) {
                    continue;
                }
                double prodDiscount = 0.0;
//                // 判断是否最后一项
//                boolean isEnd = isShopEnd && index == shopCartItems.size() - 1;
                // 如果是金额最大的一项,直接跳过,最后在处理
                if(Objects.equals(shopCartItem.getSkuId(),maxAmountSkuId)){
                    continue;
                }
                // 折扣
                if (level.getDiscountType() == 0 || categorySet.contains(shopCartItem.getCategoryId())) {
                    prodDiscount = Arith.div(Arith.mul(shopCartItem.getActualTotal(), discount), 10, 2);
                    if (Arith.add(Arith.add(levelDiscount, reduceSum), prodDiscount) > maxLevelFeeTotal) {
                        // 总折扣金额减去当前累计的折扣金额,就为最后一件商品分摊的等级优惠金额
                        prodDiscount = Arith.sub(Arith.sub(maxLevelFeeTotal, levelDiscount), reduceSum);
                    }
                }
                // 计算商品分摊的金额
                shopCartItem.setPlatformShareReduce(Arith.add(shopCartItem.getPlatformShareReduce(), prodDiscount));
                shopCartItem.setLevelReduce(prodDiscount);
                reduceSum = Arith.add(reduceSum, Arith.roundByBanker(prodDiscount, 2));
            }
            // 设置店铺的实际总值、积分优惠金额和订单优惠金额
            shopCartOrder.setLevelReduce(reduceSum);
            levelDiscount = Arith.add(levelDiscount, reduceSum);
            // 判断用户等级是否自营店包邮
            if (Objects.equals(shopCartOrder.getShopId(), Constant.MAIN_SHOP) && level.getIsFreeFee() == 1) {
                if (shopCartOrder.getTransFee() > 0) {
                    freeTransFee = shopCartOrder.getTransFee();
                    shopCartOrder.setTransFee(0.0);
                    shopCartOrder.setFreeTransFee(shopCartOrder.getTransFee() + freeTransFee);
                }
            }
        }
        // 最后一项处理,将计算偏差的金额给最后的最大的一项
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            // 如果可用范围为自营店不为当前店铺直接下一次循环
            if (level.getDiscountRange() == 1 && !Objects.equals(shopCartOrder.getShopId(), 1L)) {
                continue;
            }
            for (ShopCartItemDto shopCartItem : shopCartItems) {
                if (!Objects.equals(shopCartItem.getShopId(), shopCartOrder.getShopId())) {
                    continue;
                }
                // 如果是金额最大的一项,直接跳过,最后在处理
                if (!Objects.equals(shopCartItem.getSkuId(), maxAmountSkuId)) {
                    continue;
                }
                // 总折扣金额减去当前累计的折扣金额,就为最后一件商品分摊的等级优惠金额
                double prodDiscount = Arith.sub(maxLevelFeeTotal, levelDiscount);
                // 计算商品分摊的金额
                shopCartItem.setPlatformShareReduce(Arith.add(shopCartItem.getPlatformShareReduce(), prodDiscount));
                shopCartItem.setLevelReduce(prodDiscount);
                // 设置店铺的实际总值、积分优惠金额和订单优惠金额
                shopCartOrder.setLevelReduce(Arith.add(shopCartOrder.getLevelReduce(), prodDiscount));
                levelDiscount = Arith.add(levelDiscount, prodDiscount);
                break;
            }
        }
        shopCartOrderMerger.setTotalLevelAmount(levelDiscount);
        // 设置运费优惠金额
        shopCartOrderMerger.setFreeTransFee(freeTransFee);
    }
    /**
     * 计算出总共可以折扣的金额
     *
     * @param shopCartItems 全部商品项
     * @param level         等级
     * @param categorySet   分类
     * @return 总折扣金额
     */
    private double getLevelFeeTotal(List<ShopCartItemDto> shopCartItems, UserLevel level, Set<Long> categorySet) {
        double totalFee = 0.0;
        double maxAmount = 0.0;
        maxAmountSkuId = 0L;
        for (ShopCartItemDto shopCartItem : shopCartItems) {
            // 折扣
            if (level.getDiscountType() == 0 || categorySet.contains(shopCartItem.getCategoryId())) {
                totalFee = Arith.add(totalFee, shopCartItem.getActualTotal());
                maxAmountSkuId = shopCartItem.getActualTotal() > maxAmount ? shopCartItem.getSkuId() : maxAmountSkuId;
                maxAmount = Math.max(shopCartItem.getActualTotal(),maxAmount);
            }
        }
        return Arith.div(Arith.mul(totalFee, Arith.sub(10, level.getDiscount())), 10, 2);
    }
}
yami-shop-user/yami-shop-user-common/pom.xml
New file
@@ -0,0 +1,21 @@
<?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-user</artifactId>
        <groupId>com.yami.shop</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>yami-shop-user-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-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserBalanceCouponMapper.java
New file
@@ -0,0 +1,46 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.Coupon;
import com.yami.shop.user.common.model.UserBalanceCoupon;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Set;
/**
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
public interface UserBalanceCouponMapper extends BaseMapper<UserBalanceCoupon> {
    /**
     * 删除余额、优惠券关联信息
     * @param balanceId  充值余额id
     * @param couponIdSet 优惠券id列表
     */
    void removeByBalaceIdAndCouponId(@Param("balanceId") Long balanceId, @Param("couponIdSet") Set<Long> couponIdSet);
    /**
     * 批量更新余额优惠券关联信息
     * @param balanceId  充值余额id
     * @param couponList 优惠券列表
     */
    void updateBatchByCoupons(@Param("balanceId") Long balanceId, @Param("couponList") List<Coupon> couponList);
    /**
     * 删除余额、优惠券关联信息
     * @param balanceId 充值余额id
     */
    void removeByBalanceId(@Param("balanceId") Long balanceId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserBalanceLogMapper.java
New file
@@ -0,0 +1,146 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.bean.param.CustomerPayParam;
import com.yami.shop.bean.param.CustomerReqParam;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.user.common.dto.UserBalanceLogDto;
import com.yami.shop.user.common.model.UserBalanceLog;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
 * 余额充值记录
 *
 * @author YXF
 * @date 2020-09-09 17:38:30
 */
public interface UserBalanceLogMapper extends BaseMapper<UserBalanceLog> {
    /**
     * 分页获取余额日志列表
     *
     * @param page   分页信息
     * @param userId 用户id
     * @return 余额日志列表
     */
    PageParam<UserBalanceLogDto> getLogPage(PageParam<UserBalanceLogDto> page, @Param("userId") String userId);
    /**
     * 统计用户总充值金额
     *
     * @param userId 用户id
     * @return 用户总充值金额
     */
    Double countUserRechargeAmount(@Param("userId") String userId);
    /**
     * 统计用户余额充值次数
     *
     * @param userId 用户id
     * @return 用户余额充值次数
     */
    Integer countUserRechargeNum(@Param("userId") String userId);
    /**
     * 获取用户最新的一次余额充值时间
     *
     * @param userId 用户id
     * @return 用户最新的一次余额充值时间
     */
    Date getRecentRechargeTime(@Param("userId") String userId);
    /**
     * 平台查询某个用户的余额明细
     *
     * @param page   分页信息
     * @param userId 用户id
     * @return 用户的余额明细列表
     */
    IPage<UserBalanceLog> getPageByUserId(PageParam<UserBalanceLog> page, @Param("userId") String userId);
    /**
     * 根据充值金额,获取用户id列表
     *
     * @param isPayed   是否支付
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param minAmount 最小金额
     * @param maxAmount 最大金额
     * @return 用户id列表
     */
    List<String> listUserIdByRechargeAmount(@Param("isPayed") Integer isPayed,
                                            @Param("startDate") Date startDate,
                                            @Param("endDate") Date endDate,
                                            @Param("minAmount") BigDecimal minAmount,
                                            @Param("maxAmount") BigDecimal maxAmount);
    /**
     * 根据充值次数,获取用户id列表
     *
     * @param isPayed   是否支付
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param minNum    最小次数
     * @param maxNum    最大次数
     * @return 用户id列表
     */
    List<String> listUserIdByRechargeNum(@Param("isPayed") Integer isPayed,
                                         @Param("startDate") Date startDate,
                                         @Param("endDate") Date endDate,
                                         @Param("minNum") Long minNum,
                                         @Param("maxNum") Long maxNum);
    /**
     * 获取充值次数大于某个值的用户id列表
     *
     * @param isPayed   是否支付
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param minNum    最小次数
     * @return 用户id列表
     */
    List<String> listUserIdByRechargeNums(@Param("isPayed") Integer isPayed,
                                         @Param("startDate") Date startDate,
                                         @Param("endDate") Date endDate,
                                         @Param("minNum") Long minNum
                                         );
    /**
     * 时间段类,进行充值的会员人数,同一个人多次充值计为1
     *
     * @param param 参数
     * @return
     */
    int countUserRechargeNumByDateRange(@Param("param") CustomerReqParam param);
    /**
     * 时间段类,进行充值的会员人数,同一个人多次充值计为1
     *
     * @param param 参数
     * @return
     */
    List<CustomerPayParam> countUserRechargeNumByTime(@Param("param") CustomerReqParam param);
    /**
     * 获取用户最新充值余额的记录
     *
     * @param userId
     * @return
     */
    UserBalanceLog getMaxCrtTimeByUserId(@Param("userId") String userId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserBalanceMapper.java
New file
@@ -0,0 +1,41 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.UserBalance;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 余额充值级别表
 *
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
public interface UserBalanceMapper extends BaseMapper<UserBalance> {
    /**
     * 查询余额信息
     * @param balanceId 余额id
     * @param launch  true:只查询投放状态的优惠券 false: 全部
     * @return
     */
    UserBalance getBalanceInfo(@Param("balanceId") Long balanceId,@Param("launch") Boolean launch);
    /**
     * 获取余额充值模板列表
     * @return 余额充值模板列表
     */
    List<UserBalance> getBalanceList();
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserGrowthLogMapper.java
New file
@@ -0,0 +1,42 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.user.common.model.UserGrowthLog;
import org.apache.ibatis.annotations.Param;
/**
 * 用户成长值记录
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserGrowthLogMapper extends BaseMapper<UserGrowthLog> {
    /**
     * 分页获取用户成长值记录
     * @param page 分页信息
     * @param userGrowthLog 筛选条件
     * @return 用户成长值记录列表
     */
    Page<UserGrowthLog> getPage(PageParam<UserGrowthLog> page, @Param("userGrowthLog")UserGrowthLog userGrowthLog);
    /**
     * 根据用户id,获取用户成长值记录列表
     * @param page 分页信息
     * @param userId 用户id
     * @return 列表
     */
    IPage<UserGrowthLog> getPageByUserId(@Param("page") PageParam<UserGrowthLog> page, @Param("userId") String userId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelCategoryMapper.java
New file
@@ -0,0 +1,46 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.UserLevelCategory;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 等级分类关联
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelCategoryMapper extends BaseMapper<UserLevelCategory> {
    /**
     * 根据等级id,获取等级关联的分类id列表
     * @param id 等级id
     * @return 分类id列表
     */
    List<Long> getCategoryIdByLevelId(@Param("id") Long id);
    /**
     * 批量保存等级分类关联信息
     * @param categorys 分类id列表
     * @param id 等级id
     */
    void insertBatch(@Param("categorys") Long[] categorys, @Param("id") Long id);
    /**
     * 批量删除等级分类关联信息
     * @param categorys 分类id列表
     * @param id 等级id
     */
    void delBatch(@Param("categorys") Long[] categorys, @Param("id") Long id);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelCouponMapper.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.Coupon;
import com.yami.shop.user.common.model.UserLevelCoupon;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 等级优惠券关联
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelCouponMapper extends BaseMapper<UserLevelCoupon> {
    /**
     * 批量插入等级优惠券关联信息
     * @param coupons 优惠券id列表
     * @param id 等级id
     */
    void insertBatchCoupon(@Param("coupons") Long[] coupons, @Param("id") Long id);
    /**
     * 批量删除等级优惠券关联信息
     * @param coupons 优惠券id列表
     * @param id 等级id
     */
    void delBatchCoupon(@Param("coupons") Long[] coupons, @Param("id") Long id);
    /**
     * 根据等级id,获取优惠券列表信息
     * @param id 等级id
     * @return 优惠券列表
     */
    List<Coupon> getCouponListByLevelId(@Param("id")Long id);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelLogMapper.java
New file
@@ -0,0 +1,127 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.param.CustomerPayParam;
import com.yami.shop.bean.param.CustomerReqParam;
import com.yami.shop.bean.param.MemberGrowthDetailParam;
import com.yami.shop.bean.param.MemberGrowthReqParam;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.user.common.model.UserLevelLog;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * 用户等级记录
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelLogMapper extends BaseMapper<UserLevelLog> {
    /**
     * 分页获取用户等级记录
     *
     * @param page         分页信息
     * @param userLevelLog 筛选信息
     * @return 用户等级记录列表
     */
    Page<UserLevelLog> getPage(Page<UserLevelLog> page, @Param("userLevelLog") UserLevelLog userLevelLog);
    /**
     * 获取用户最高的等级(普通会员)
     *
     * @param userId 用户id
     * @return 用户等级
     */
    Integer getMaxLevelByUserId(@Param("userId") String userId);
    /**
     * 统计升级会员数
     *
     * @param param 筛选数据
     * @return 升级会员数
     */
    Integer countGrowthMember(@Param("param") CustomerReqParam param);
    /**
     * 统计每个等级中的会员数
     *
     * @param param 筛选数据
     * @return 等级及等级中的会员数量
     */
    List<MemberGrowthDetailParam> countGrowthMemberByParam(@Param("param") MemberGrowthReqParam param);
    /**
     * 根据用户数量,筛选用户
     *
     * @param isPayed   是否支付
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param minNum    最小用户数
     * @param maxNum    最大用户数
     * @return 用户id列表
     */
    List<String> listUserIdByRechargeNum(@Param("isPayed") Integer isPayed,
                                         @Param("startDate") Date startDate,
                                         @Param("endDate") Date endDate,
                                         @Param("minNum") Long minNum,
                                         @Param("maxNum") Long maxNum);
    /**
     * 根据开始结束时间及支付状态,筛选用户
     *
     * @param isPayed   是否支付
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 用户id列表
     */
    List<String> listUserIdByEarliestRechargeTime(@Param("isPayed") Integer isPayed,
                                                  @Param("startDate") Date startDate,
                                                  @Param("endDate") Date endDate);
    /**
     * 获取用户最新的购买等级记录信息
     *
     * @param userId 用户id
     * @return 等级记录信息
     */
    UserLevelLog getMaxCrtTimeByUserId(@Param("userId") String userId);
    /**
     * 获取付费会员购买记录
     *
     * @param page
     * @param userLevelLog
     * @return
     */
    IPage<UserLevelLog> pageBuyLevelLog(@Param("page") PageParam<UserLevelLog> page, @Param("userLevelLog") UserLevelLog userLevelLog);
    /**
     * 根据时间获取升级会员信息
     *
     * @param param 时间
     * @return 会员数量
     */
    List<CustomerPayParam> countGrowthMemberByTime(@Param("param") CustomerReqParam param);
    /**
     * 获取支付会员数
     *
     * @param param
     * @return
     */
    Integer countPayUserByTime(@Param("param") CustomerReqParam param);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelMapper.java
New file
@@ -0,0 +1,77 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.user.common.dto.LevelDetailDto;
import com.yami.shop.user.common.dto.UserLevelDto;
import com.yami.shop.user.common.model.UserLevel;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelMapper extends BaseMapper<UserLevel> {
    /**
     * 获取用户所在等级的,等级及等级关联的分类id列表信息
     * @param user 用户信息
     * @return 等级及等级关联的分类id列表
     */
    UserLevel selectOneAndCategory(@Param("user") UserExtension user);
    /**
     * 根据等级类型,获取对应的等级列表
     * @param userLevelType 等级类型
     * @return 等级列表
     */
    List<UserLevelDto> getList(@Param("userLevelType") Integer userLevelType);
    /**
     * 获取等级列表, 等级包含等级关联的分类id列表 (普通会员等级)
     * @param nowGrowth 所需成长值
     * @param level 等级
     * @return  等级列表
     */
    List<UserLevel> selectListAndCoupons(@Param("nowGrowth") Integer nowGrowth, @Param("level") Integer level);
    /**
     * 获取等级列表, 等级包含等级关联的分类id列表 (付费会员等级)
     * @param level 等级
     * @return  等级列表
     */
    UserLevel selectLevelAndCoupons(@Param("level") Integer level);
    /**
     * 获取等级列表,等级包含等级关联的权限列表信息
     * @param levelType 等级类型
     * @return 等级列表
     */
    List<LevelDetailDto> selectLevelAndRights(@Param("levelType") Integer levelType);
    /**
     * 更新普通会员等级的状态为启用
     */
    void setStatusByLevelType();
    /**
     * 获取等级列表, 等级包含等级关联的分类id列表 (普通会员等级)(等级倒序)
     * @param nowGrowth 所需成长值
     * @param level 等级
     * @return  等级列表
     */
    List<UserLevel> selectListAndCouponsLtNowGrowth(@Param("nowGrowth") Integer nowGrowth, @Param("level") Integer level);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserLevelRightsMapper.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.UserLevelRights;
import org.apache.ibatis.annotations.Param;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelRightsMapper extends BaseMapper<UserLevelRights> {
    /**
     * 批量插入等级权益信息
     * @param rightsList 权益列表
     * @param id 等级id
     */
    void insertBatchRights(@Param("rightsList") Long[] rightsList,@Param("id") Long id);
    /**
     * 批量删除等级权益信息
     * @param rightsList 权益列表
     * @param id 等级id
     */
    void delBatchRights(@Param("rightsList")Long[] rightsList,@Param("id") Long id);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserRightsMapper.java
New file
@@ -0,0 +1,41 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.UserRights;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserRightsMapper extends BaseMapper<UserRights> {
    /**
     * 更新权益状态信息
     * @param rightsId 权益id
     * @param status 状态
     * @return 是否成功更新
     */
    Boolean setStatua(@Param("rightsId") Long rightsId, @Param("status")Integer status);
    /**
     * 根据等级id,获取关联的权益列表
     * @param id 等级id
     * @param levelType 等级类型
     * @return 权益列表
     */
    List<Long> getUserRightsIdListByLevelId(@Param("id")Long id,@Param("levelType") Integer levelType);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserScoreDetailMapper.java
New file
@@ -0,0 +1,88 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.UserScoreDetail;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.Date;
import java.util.List;
/**
 *
 *
 * @author lhd
 * @date 2020-05-25 15:31:02
 */
public interface UserScoreDetailMapper extends BaseMapper<UserScoreDetail> {
    /**
     * 查询有积分过期或抵现记录的用户
     * @param expireTime 过期时间
     * @return 积分过期列表
     */
    List<UserScoreDetail> listExpireScoreDetail(@Param("expireTime") DateTime expireTime);
    /**
     * 修改状态为0的积分明细为过期状态
     * @param dateTime 过期时间
     */
    void updateExpireScoreDetail(@Param("expireTime") DateTime dateTime);
    /**
     * 查询已经过期但还没标记的积分
     * @param userId 用户id
     * @param expireTime 过期时间
     * @param status 状态
     * @return 用户积分记录列表
     */
    List<UserScoreDetail> listByUserIdAndExpireTimeAndStatus(@Param("userId") String userId, @Param("expireTime") Date expireTime, @Param("status") Integer status);
    /**
     * 查询用户积分详细表数据
     * @param userId 用户id
     * @param status 状态
     * @return 用户积分详细表数据
     */
    List<UserScoreDetail> listByCreateTime(@Param("userId") String userId, @Param("status") Integer status);
    /**
     * 查询用户积分记录列表
     * @param userId 用户id
     * @param status 状态
     * @param current 开始搜索的索引
     * @param size 分页的大小
     * @return
     */
    List<UserScoreDetail> listByCreateTimeAndPage(@Param("userId") String userId, @Param("status") Integer status, @Param("current") Integer current, @Param("size") Integer size);
    /**
     * 批量更新用户积分状态
     *
     * @param status        状态
     * @param userScoreGetIds 用户积分ids
     */
    void batchUpdateUserScoreGetStatus(@Param("status") Integer status, @Param("userScoreGetIds") List<Long> userScoreGetIds);
    @Select("select usable_score from tz_user_score_detail where user_id = #{userId} and status = 1")
    Long selectUsableScoreByUserId(String userId);
    /**
     * 根据用户id更新用户积分
     * @param userId 用户id
     * @param amount 额数
     */
    @Update("update tz_user_score_detail set usable_score = usable_score + #{amount},update_time = NOW() where user_id = #{userId}")
    Boolean updateScoreByUserId(@Param("userId") String userId,@Param("amount") Long amount);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserScoreLockMapper.java
New file
@@ -0,0 +1,54 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.user.common.model.UserScoreLock;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 积分锁定信息
 *
 * @author lhd
 * @date 2022-05-06 17:27:53
 */
public interface UserScoreLockMapper extends BaseMapper<UserScoreLock> {
    /**
     * 将锁定状态标记为已解锁
     *
     * @param status
     * @param userScoreLockIds 用户锁定的ids
     * @return
     */
    int unLockByIds(@Param("status") Integer status, @Param("userScoreLockIds") List<Long> userScoreLockIds);
    /**
     * 将锁定状态标记为已解锁
     *
     * @param status
     * @param orderNumbers 用户订单号集合
     * @return
     */
    int unLockByOrderNumbers(@Param("status") Integer status, @Param("orderNumbers") List<String> orderNumbers);
    /**
     * 获取需要解锁的用户积分id列表
     *
     * @param orderNumber 订单号
     * @return 用户的积分id列表
     */
    List<UserScoreLock> listUserScoreLocksByOrderNumber(@Param("orderNumber") String orderNumber);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserScoreLogMapper.java
New file
@@ -0,0 +1,55 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.user.common.model.UserScoreLog;
import org.apache.ibatis.annotations.Param;
/**
 * 用户积分记录
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserScoreLogMapper extends BaseMapper<UserScoreLog> {
    /**
     * 获取签到的天数
     * @param userId 用户id
     * @return 签到的天数
     */
    Integer getConsecutiveDays(@Param("userId") String userId);
    /**
     * 分页获取用户积分记录
     * @param page 分页信息
     * @param userScoreLog 筛选信息
     * @return 用户积分记录
     */
    Page<UserScoreLog> getPage(PageParam<UserScoreLog> page, @Param("userScoreLog") UserScoreLog userScoreLog);
    /**
     * 累计积分
     * @param userId 用户id
     * @return 累计积分
     */
    Integer countSumScore(@Param("userId") String userId);
    /**
     * 获取某个用户的积分明细
     * @param page 分页信息
     * @param userId 用户id
     * @return 指定用户id的积分明细
     */
    IPage<UserScoreLog> getPageByUserId(@Param("page") PageParam<UserScoreLog> page, @Param("userId") String userId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserTagMapper.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.user.common.model.UserTag;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
/**
 * 客户标签
 *
 * @author LGH
 * @date 2020-09-09 11:31:16
 */
public interface UserTagMapper extends BaseMapper<UserTag> {
    /**
     * 批量修改标签人数
     * @param tagUser 标签人数map
     */
    void updateBatch(@Param("tagUser") Map<Long, Integer> tagUser);
    /**
     * 根据参数查询标签列表
     * @param page 分页参数
     * @param tagType 标签类型
     * @param tagName 标签名称
     * @return 标签列表
     */
    IPage<UserTag> pageUserTagByParam(Page page, @Param("tagType") Integer tagType, @Param("tagName") String tagName);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dao/UserTagUserMapper.java
New file
@@ -0,0 +1,57 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yami.shop.bean.param.UserTagParam;
import com.yami.shop.user.common.model.UserTagUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 用户和标签关联表
 *
 * @author LGH
 * @date 2020-09-10 08:44:22
 */
public interface UserTagUserMapper extends BaseMapper<UserTagUser> {
    /**
     * 获取标签关联信息根据用户id和标签id
     * @param userId 用户id
     * @param userTagId 标签id
     * @return 标签关联信息
     */
    UserTagUser getByUserIdAndTagId(@Param("userId") String userId, @Param("userTagId") Long userTagId);
    /**
     * 获取用户的标签数量
     * @param userId 用户id
     * @param userTagId 标签id
     * @return 结果
     */
    Integer countByUserIdAndTagId(@Param("userId") String userId, @Param("userTagId") Long userTagId);
    /**
     * 获取用户的标签列表
     * @param userId 用户id
     * @return 标签列表
     */
    List<UserTagParam> getUserTagsUserByUserId(@Param("userId") String userId);
    /**
     * 移除标签通过用户id和标签关联id
     * @param userId 用户id
     * @param userTagId 用户标签关联id
     * @return 结果
     */
    int removeByUserIdAndTagId(@Param("userId") String userId, @Param("userTagId") Long userTagId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/LevelDetailDto.java
New file
@@ -0,0 +1,137 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import com.baomidou.mybatisplus.annotation.TableField;
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.io.Serializable;
import java.util.List;
/**
 * 会员等级
 *
 * @author LHD
 * @date 2020-02-26 16:03:14
 */
@Data
public class LevelDetailDto implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @Schema(description = "主键" )
    private Long id;
    /**
     * 等级
     */
    @Schema(description = "等级" )
    private Integer level;
    /**
     * 等级名称
     */
    @Schema(description = "等级名称" )
    private String levelName;
    /**
     * 等级条件 0 普通会员 1 付费会员
     */
    @Schema(description = "等级条件 0 普通会员 1 付费会员" )
    private Integer levelType;
    /**
     * 所需成长值
     */
    @Schema(description = "所需成长值" )
    private Integer needGrowth;
    /**
     * 付费会员价格
     */
    @Schema(description = "付费会员价格" )
    private Double needAmount;
    /**
     * 有效期(天)
     */
    @Schema(description = "等级" )
    private Integer term;
    /**
     * 期数类型
     */
    @Schema(description = "等级" )
    private Integer termType;
    /**
     * 背景图片
     */
    @Schema(description = "等级" )
    @JsonSerialize(using = ImgJsonSerializer.class)
    private String img;
    /**
     *  权益数组
     */
    @TableField(exist = false)
    @Schema(description = "权益数组" )
    private List<UserRightsDto> userRights;
//    /**
//     * 折扣范围 0 全平台 1 自营店
//     */
//    @Schema(description = "等级" )
//    private Integer discountRange;
//    /**
//     * 折扣方式 0 全部商品 1 分类下的商品
//     */
//    @Schema(description = "等级" )
//    private Integer discountType;
//    /**
//     * 会员折扣
//     */
//    @Schema(description = "等级" )
//    private Double discount;
//    /**
//     * 赠送积分
//     */
//    @Schema(description = "等级" )
//    private Integer presScore;
//    /**
//     * 积分回馈倍率
//     */
//    @Schema(description = "等级" )
//    private Double rateScore;
//    /**
//     * 是否包邮 0:不包邮 1:包邮
//     */
//    private Integer isFreeFee;
//    /**
//     * 优惠券列表
//     */
//    @TableField(exist = false)
//    private List<Coupon> couponList;
//
//    @TableField(exist = false)
//    private List<Long> couponIds;
//
//    /**
//     * 等级分类列表
//     */
//    @TableField(exist = false)
//    private List<Long> categoryIds;
//
//    @TableField(exist = false)
//    private List<Long> categorys;
//
//    /**
//     *  权益id数组
//     */
//    @TableField(exist = false)
//    private List<Long> userRightsIds;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/LevelDto.java
New file
@@ -0,0 +1,94 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 *
 * @author LHD
 * @date 2019-12-19 10:27:46
 */
@Data
public class LevelDto implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 用户昵称
     */
    @Schema(description = "用户昵称" )
    private String nickName;
    /**
     * 用户当前等级
     */
    @Schema(description = "用户当前会员等级名称" )
    private String levelName;
    /**
     * 等级条件 0 普通会员 1 付费会员
     */
    @Schema(description = "用户当前会员等级类型 0 普通会员 1 付费会员" )
    private Integer levelType;
    /**
     * 用户年费会员过期时间
     */
    @Schema(description = "用户会员过期时间" )
    private Date endTime;
    /**
     * 用户当前等级
     */
    @Schema(description = "用户当前等级" )
    private LevelDetailDto userLevel;
    /**
     * 用户当前等级所需成长值
     */
    @Schema(description = "当前等级所需成长值" )
    private Integer needGrowth;
    /**
     * 用户当前成长值
     */
    @Schema(description = "用户当前成长值" )
    private Integer growth;
    /**
     * 用户当前积分
     */
    @Schema(description = "用户当前积分" )
    private Long score = 0L;
    /**
     * 等级列表
     */
    @Schema(description = "等级列表" )
    private List<LevelDetailDto> userLevels;
    /**
     * 下一等级名称
     */
    @Schema(description = "下一等级名称" )
    private String nextLevelName;
    /**
     * 下一等级所需成长值
     */
    @Schema(description = "下一等级所需成长值" )
    private Integer nextGrowth;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/ScoreDataDto.java
New file
@@ -0,0 +1,99 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * 积分中心信息
 *
 * @author LHD
 * @date 2019-12-19 10:27:46
 *
 * @author yami
 */
@Data
public class ScoreDataDto implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 签到积分列表
     */
    @Schema(description = "签到积分列表" )
    private List<Integer> scoreList;
    /**
     * 用户积分
     */
    @Schema(description = "用户积分" )
    private Long score;
    /**
     * 上次结算过期的积分
     */
    @Schema(description = "上次结算过期的积分" )
    private Long expireScore;
    /**
     * 过期时间(年)
     */
    @Schema(description = "过期时间(年)" )
    private Integer expireYear;
    /**
     * 积分过期开关
     */
    @Schema(description = "积分过期开关" )
    private Boolean scoreExpireSwitch;
    /**
     * 等级名称
     */
    @Schema(description = "等级名称" )
    private String levelName;
    /**
     * 等级类型 0 普通会员 1 付费会员
     */
    @Schema(description = "等级类型 0 普通会员 1 付费会员" )
    private Integer levelType;
    /**
     * 用户当前成长值
     */
    @Schema(description = "用户当前成长值" )
    private Integer growth;
    /**
     * 注册可获取积分
     */
    @Schema(description = "注册可获取积分" )
    private Long registerScore;
    /**
     * 购物可获取积分
     */
    @Schema(description = "购物可获取积分" )
    private Double shopScore;
    /**
     * 是否已经签到 1是 0否
     */
    @Schema(description = "是否已经签到 1是 0否" )
    private Integer isSignIn;
    /**
     * 是否已经注册 1是 0否
     */
    @Schema(description = "是否已经注册 1是 0否" )
    private Integer isRegister;
    /**
     * 签到第几天
     */
    @Schema(description = "签到第几天" )
    private Integer signInCount;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/ScoreOrderMergerDto.java
New file
@@ -0,0 +1,68 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import com.yami.shop.bean.app.dto.ProductItemDto;
import com.yami.shop.bean.app.dto.UserAddrDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * 积分商品订单合并信息
 * @author LHD
 */
@Data
public class ScoreOrderMergerDto {
    @Schema(description = "实际总值" , required = true)
    private Double actualTotal;
    @Schema(description = "商品总值" , required = true)
    private Double total;
    @Schema(description = "用户等级免运费金额" , required = true)
    private Double freeTransfee = 0.0;
    @Schema(description = "总运费" , required = true)
    private Double totalTransfee;
    @Schema(description = "商品总数" , required = true)
    private Integer totalCount;
    @Schema(description = "地址Dto" , required = true)
    private UserAddrDto userAddr;
    @Schema(description = "商品信息" , required = true)
    private ProductItemDto productItemDto;
    @Schema(description = "msgId" ,required=true)
    private String msgId;
    @Schema(description = "userId" ,required=true)
    private String userId;
    @Schema(description = "店铺id" , required = true)
    private Long shopId;
    @Schema(description = "订单编号" , required = true)
    private String orderNumber;
    @Schema(description = "用户是否选择积分抵现(0不使用 1使用 默认不使用)" )
    private Integer isScorePay;
    @Schema(description = "订单优惠金额(所有店铺优惠金额和使用积分抵现相加)" , required = true)
    private Double orderReduce = 0.0;
    @Schema(description = "订单备注" ,required=true)
    private String remarks;
    @Schema(description = "每次订单提交时的uuid" )
    private String uuid;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserBalanceDto.java
New file
@@ -0,0 +1,68 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.yami.shop.user.common.model.Coupon;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
 * 余额充值级别表
 *
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
@Data
public class UserBalanceDto{
    /**
     * 主键
     */
    @Schema(description = "主键" )
    private Long balanceId;
    /**
     * 充值余额标题
     */
    @Schema(description = "充值余额标题" )
    private String balanceTitle;
    /**
     * 充值金额
     */
    @Schema(description = "充值金额" )
    private Double rechargeAmount;
    /**
     * 背景图片
     */
    @Schema(description = "背景图片" )
    private String img;
    /**
     * 赠送金额
     */
    @Schema(description = "赠送金额" )
    private Double presAmount;
    /**
     * 赠送积分
     */
    @Schema(description = "赠送积分" )
    private Integer presScore;
    /**
     * 赠送成长值
     */
    @Schema(description = "赠送成长值" )
    private Integer presGrowth;
    @TableField(exist = false)
    @Schema(description = "赠送优惠券列表" )
    private List<Coupon> couponList;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserBalanceLogDto.java
New file
@@ -0,0 +1,50 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
 * 余额充值记录
 *
 * @author YXF
 * @date 2020-09-09 17:38:30
 */
@Data
public class UserBalanceLogDto{
    /**
     * 创建时间
     */
    @Schema(description = "升级时间" )
    private Date createTime;
    /**
     * 改变余额
     */
    @Schema(description = "改变余额" )
    private Double changeBalance;
    /**
     * 收支类型 0支出 1收入
     */
    @Schema(description = "收支类型 0支出 1收入" )
    private Integer ioType;
    /**
     * 1:充值 2:使用 3:赠送
     */
    @Schema(description = "1:充值 2:赠送 3:支付 4:退款" )
    private Integer type;
    @Schema(description = "订单号列表" )
    private String orderNumbers;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserLevelDto.java
New file
@@ -0,0 +1,106 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import com.yami.shop.user.common.model.Coupon;
import lombok.Data;
import java.util.List;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
public class UserLevelDto{
    /**
     * 主键
     */
    private Long id;
    /**
     * 等级
     */
    private Integer level;
    /**
     * 等级名称
     */
    private String levelName;
    /**
     * 等级条件 0 普通会员 1 付费会员
     */
    private Integer levelType;
    /**
     * 所需成长值
     */
    private Integer needGrowth;
    /**
     * 付费会员价格
     */
    private Double needAmount;
    /**
     * 有效期(天)
     */
    private Integer term;
    /**
     * 期数类型
     */
    private Integer termType;
    /**
     * 背景图片
     */
    private String img;
    /**
     * 折扣范围 0 全平台 1 自营店
     */
    private Integer discountRange;
    /**
     * 折扣方式 0 全部商品 1 分类下的商品
     */
    private Integer discountType;
    /**
     * 会员折扣
     */
    private Double discount;
    /**
     * 赠送积分
     */
    private Long presScore;
    /**
     * 积分回馈倍率
     */
    private Double rateScore;
    /**
     * 是否包邮 0:不包邮 1:包邮
     */
    private Integer isFreeFee;
    /**
     * 1:已更新 0:停用 -1:未更新(等级修改后,用户等级的更新)
     */
    private Integer status;
    /**
     * 优惠券列表
     */
    private List<Coupon> couponList;
    /**
     *  分类id数组
     */
    private List<Long> categorys;
    /**
     *  权益id数组
     */
    private List<Long> userRightsIds;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserRightsDto.java
New file
@@ -0,0 +1,63 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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;
import java.io.Serializable;
/**
 * 会员等级权益
 *
 * @author LHD
 * @date 2020-02-26 16:03:14
 */
@Data
public class UserRightsDto implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 权益id
     */
    @Schema(description = "权益id" )
    private Long rightsId;
    /**
     * 权益名称
     */
    @Schema(description = "权益名称" )
    private String rightsName;
    /**
     * 权益图标
     */
    @JsonSerialize(using = ImgJsonSerializer.class)
    @Schema(description = "权益名称" )
    private String icon;
    /**
     * 权益简介
     */
    @Schema(description = "权益名称" )
    private String description;
    /**
     * 0系统核销 1商家线下核销
     */
    @Schema(description = "0系统核销 1商家线下核销" )
    private Integer serviceType;
    /**
     * 状态:-1:禁用 1:正常(仅用于系统核销)
     */
    private Integer status;
    /**
     * 顺序
     */
    private Integer seq;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/dto/UserTagDto.java
New file
@@ -0,0 +1,297 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * @author yami
 */
@Data
public class UserTagDto implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 新增标签校验
     */
    public interface AddUserTag {
    }
    /**
     * 修改标签校验
     */
    public interface UpdateUserTag {
    }
    /**
     * 自增id
     */
    @Schema(description = "自增id" )
    @NotNull(message = "自增id不能为空", groups = UpdateUserTag.class)
    private Long userTagId;
    /**
     * 标签名字
     */
    @Schema(description = "标签名字" )
    @NotBlank(message = "标签名字不能为空", groups = AddUserTag.class)
    @NotBlank(message = "标签名字不能为空", groups = UpdateUserTag.class)
    private String tagName;
    /**
     * 标签类型0手动1条件
     */
    @Schema(description = "标签类型0手动1条件" )
    @Max(value = 1, message = "只能为0或1", groups = AddUserTag.class)
    @Min(value = 0, message = "只能为0或1", groups = AddUserTag.class)
    @NotNull(message = "标签类型不能为空。", groups = AddUserTag.class)
    private Integer tagType;
    /**
     * 系统标签是否开启
     */
    @Schema(description = "系统标签是否开启" )
    @Max(value = 1, message = "只能为0或1", groups = UpdateUserTag.class)
    @Min(value = 0, message = "只能为0或1", groups = UpdateUserTag.class)
    private Integer isSysTurnOn;
    /**
     * 成为客户开始时间
     */
    @Schema(description = "成为客户开始时间" )
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime registerMinTime;
    /**
     * 成为客户结束时间
     */
    @Schema(description = "成为客户结束时间" )
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime registerMaxTime;
    /**
     * 清空成为客户时间标记
     */
    @Schema(description = "清空成为客户时间标记" )
    private Boolean clearRegisterTime;
    /**
     * 关注开始时间
     */
    @Schema(description = "关注开始时间" )
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime subscribeMinTime;
    /**
     * 关注结束时间
     */
    @Schema(description = "关注结束时间" )
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime subscribeMaxTime;
    /**
     * 清空关注时间标记
     */
    @Schema(description = "清空关注时间标记" )
    private Boolean clearSubscribeTime;
    /**
     * 成为会员开始时间
     */
    @Schema(description = "成为会员开始时间" )
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime toBeMemberMinTime;
    /**
     * 成为会员结束时间
     */
    @Schema(description = "成为会员结束时间" )
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime toBeMemberMaxTime;
    /**
     * 清空成为会员时间标记
     */
    @Schema(description = "清空成为会员时间标记" )
    private Boolean clearToBeMemberTime;
    /**
     * 最近消费时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    @Schema(description = "最近消费时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)" )
    @Max(value = 8, message = "最大值为8", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Integer recentPurchaseTime;
    /**
     * 清空最近消费时间标记
     */
    @Schema(description = "清空成为会员时间标记" )
    private Boolean clearRecentPurchaseTime;
    /**
     * 消费次数时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    @Schema(description = "消费次数时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)" )
    @Max(value = 8, message = "最大值为8", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Integer purchaseNumTime;
    /**
     * 消费次数最小次数
     */
    @Schema(description = "消费次数最小次数" )
    @Max(value = 100000, message = "最大值为100000", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Long purchaseNumMinNum;
    /**
     * 消费次数最大次数
     */
    @Schema(description = "消费次数最大次数" )
    @Max(value = 100000, message = "最大值为100000", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Long purchaseNumMaxNum;
    /**
     * 清空消费次数标记
     */
    @Schema(description = "清空消费次数标记" )
    private Boolean clearPurchaseNum;
    /**
     * 消费金额时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    @Schema(description = "消费金额时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)" )
    @Max(value = 8, message = "最大值为8", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Integer purchaseAmountTime;
    /**
     * 消费金额最小金额
     */
    @Schema(description = "消费金额最小金额" )
    @DecimalMax(value = "100000000", message = "最大值为100000000", groups = {AddUserTag.class, UpdateUserTag.class})
    @DecimalMin(value = "0", message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private BigDecimal purchaseAmountMinAmount;
    /**
     * 消费金额最大金额
     */
    @Schema(description = "消费金额最大金额" )
    @DecimalMax(value = "100000000", message = "最大值为100000000", groups = {AddUserTag.class, UpdateUserTag.class})
    @DecimalMin(value = "0", message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private BigDecimal purchaseAmountMaxAmount;
    /**
     * 清空消费金额标记
     */
    @Schema(description = "清空消费次数标记" )
    private Boolean clearPurchaseAmount;
    /**
     * 订单均价时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    @Schema(description = "订单均价时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)" )
    @Max(value = 8, message = "最大值为8", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Integer orderAveragePriceTime;
    /**
     * 订单均价最小金额
     */
    @Schema(description = "订单均价最小金额" )
    @DecimalMax(value = "100000000", message = "最大值为100000000", groups = {AddUserTag.class, UpdateUserTag.class})
    @DecimalMin(value = "0", message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private BigDecimal orderAveragePriceMinAmount;
    /**
     * 订单均价最大金额
     */
    @Schema(description = "订单均价最大金额" )
    @DecimalMax(value = "100000000", message = "最大值为100000000", groups = {AddUserTag.class, UpdateUserTag.class})
    @DecimalMin(value = "0", message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private BigDecimal orderAveragePriceMaxAmount;
    /**
     * 清空订单均价标记
     */
    @Schema(description = "清空订单均价标记" )
    private Boolean clearOrderAveragePrice;
    /**
     * 充值金额时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    @Schema(description = "充值金额时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)" )
    @Max(value = 8, message = "最大值为8", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Integer rechargeAmountTime;
    /**
     * 充值金额最小金额
     */
    @Schema(description = "充值金额最小金额" )
    @DecimalMax(value = "100000000", message = "最大值为100000000", groups = {AddUserTag.class, UpdateUserTag.class})
    @DecimalMin(value = "0", message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private BigDecimal rechargeAmountMinAmount;
    /**
     * 充值金额最大金额
     */
    @Schema(description = "充值金额最大金额" )
    @DecimalMax(value = "100000000", message = "最大值为100000000", groups = {AddUserTag.class, UpdateUserTag.class})
    @DecimalMin(value = "0", message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private BigDecimal rechargeAmountMaxAmount;
    /**
     * 清空充值金额标记
     */
    @Schema(description = "清空充值金额标记" )
    private Boolean clearRechargeAmount;
    /**
     * 充值次数时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    @Schema(description = "充值次数时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)" )
    @Max(value = 8, message = "最大值为8", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Integer rechargeNumTime;
    /**
     * 充值次数最小次数
     */
    @Schema(description = "充值次数最小次数" )
    @Max(value = 100000, message = "最大值为100000", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Long rechargeNumMinNum;
    /**
     * 充值次数最大次数
     */
    @Schema(description = "充值次数最大次数" )
    @Max(value = 100000, message = "最大值为100000", groups = {AddUserTag.class, UpdateUserTag.class})
    @Min(value = 0, message = "最小值为0", groups = {AddUserTag.class, UpdateUserTag.class})
    private Long rechargeNumMaxNum;
    /**
     * 清空充值次数标记
     */
    @Schema(description = "清空充值次数标记" )
    private Boolean clearRechargeNum;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/enums/GrowthLogSourceEnum.java
New file
@@ -0,0 +1,69 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.enums;
/**
 * 成长值来源
 *
 * @Author lth
 * @Date 2021/10/19 9:37
 */
public enum GrowthLogSourceEnum {
    /**
     * 系统修改用户成长值
     */
    SYSTEM(0, "系统修改用户成长值", "System modify user growth value"),
    /**
     * 订单确认收货获取成长值
     */
    ORDER_SUCCESS(1, "订单确认收货获取成长值", "Order confirmation and receipt to obtain growth value"),
    /**
     * 订单退款退回成长值
     */
    ORDER_FAIL(2, "订单退款退回成长值", "Order refund returns growth value"),
    /**
     * 余额
     */
    BALANCE(3, "用户充值余额获取的成长值", "The growth value obtained by the user's recharge balance")
    ;
    private String cn;
    private String en;
    private final Integer num;
    public String getEn() {
        return en;
    }
    public String getCn() {
        return cn;
    }
    public Integer value() {
        return num;
    }
    GrowthLogSourceEnum(Integer num, String cn, String en){
        this.num = num;
        this.cn = cn;
        this.en = en;
    }
    public static GrowthLogSourceEnum instance(Integer value) {
        GrowthLogSourceEnum[] enums = values();
        for (GrowthLogSourceEnum sourceEnum : enums) {
            if (sourceEnum.value().equals(value)) {
                return sourceEnum;
            }
        }
        return null;
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/enums/UserRightsInfo.java
New file
@@ -0,0 +1,49 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.enums;
/**
 * 满减规则
 *
 * @author yami
 */
public enum UserRightsInfo {
    /** 打折 */
    DISCOUNT(1L),
    /** 包邮 */
    IS_FREE_FEE(2L),
    /** 送积分 */
    SCORE(3L),
    /** 送优惠券 */
    COUPON(4L),
    /** 积分倍率 */
    RATE_SCORE(5L),
    ;
    private Long id;
    public Long value() {
        return id;
    }
    UserRightsInfo(Long id){
        this.id = id;
    }
    public static UserRightsInfo instance(Integer value) {
        UserRightsInfo[] enums = values();
        for (UserRightsInfo statusEnum : enums) {
            if (statusEnum.value().equals(value)) {
                return statusEnum;
            }
        }
        return null;
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/BalanceCouponListener.java
New file
@@ -0,0 +1,39 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.event.BalanceCouponEvent;
import com.yami.shop.user.common.model.UserBalanceCoupon;
import com.yami.shop.user.common.service.UserBalanceCouponService;
import com.yami.shop.user.common.service.UserBalanceService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
 * 余额优惠券操作
 *
 * @author lhd
 */
@Component("balanceCouponListener")
@AllArgsConstructor
public class BalanceCouponListener {
    private final UserBalanceCouponService userBalanceCouponService;
    private final UserBalanceService userBalanceService;
    @EventListener(BalanceCouponEvent.class)
    public void balanceRefundListener(BalanceCouponEvent event) {
        // 根据优惠券,删除与余额模板的绑定信息
        userBalanceCouponService.remove(new LambdaQueryWrapper<UserBalanceCoupon>().eq(UserBalanceCoupon::getCouponId, event.getCouponId()));
        // 清除余额模板列表的缓存
        userBalanceService.removeCacheByBalanceId();
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/BalanceRefundListener.java
New file
@@ -0,0 +1,91 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.dto.OrderRefundDto;
import com.yami.shop.bean.enums.RefundStatusEnum;
import com.yami.shop.bean.event.BalanceRefundEvent;
import com.yami.shop.bean.model.RefundInfo;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.pay.RefundInfoDto;
import com.yami.shop.common.util.Arith;
import com.yami.shop.service.NotifyTemplateService;
import com.yami.shop.service.OrderRefundService;
import com.yami.shop.service.RefundInfoService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.model.UserBalanceLog;
import com.yami.shop.user.common.service.UserBalanceLogService;
import lombok.AllArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.Objects;
/**
 * 余额支付操作
 *
 * @author lhd
 */
@Component("balanceRefundListener")
@AllArgsConstructor
public class BalanceRefundListener {
    private final UserExtensionService userExtensionService;
    private final UserBalanceLogService userBalanceLogService;
    private final OrderRefundService orderRefundService;
    private final NotifyTemplateService notifyTemplateService;
    private final RefundInfoService refundInfoService;
    /**
     * 余额退款操作
     */
    @EventListener(BalanceRefundEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void balanceRefundListener(BalanceRefundEvent event) {
        RefundInfoDto eventRefundInfo = event.getRefundInfo();
//        int refundCount = userBalanceLogService.count(new LambdaQueryWrapper<UserBalanceLog>().eq(UserBalanceLog::getRefundSn, eventRefundInfo.getRefundSn()));
//        if (refundCount > 0) {
//            return;
//        }
//        if (eventRefundInfo.getRefundAmount() > 0) {
//            UserBalanceLog userBalanceLog = new UserBalanceLog();
//            userBalanceLog.setUserId(eventRefundInfo.getUserId());
//            userBalanceLog.setType(4);
//            userBalanceLog.setPayNo(eventRefundInfo.getPayNo());
//            userBalanceLog.setIoType(1);
//            userBalanceLog.setChangeBalance(eventRefundInfo.getRefundAmount());
//            userBalanceLog.setCreateTime(new Date());
//            userBalanceLogService.save(userBalanceLog);
//        }
//        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, eventRefundInfo.getUserId()));
//        userExtension.setTotalBalance(Arith.add(userExtension.getTotalBalance(), eventRefundInfo.getRefundAmount()));
//        userExtension.setUpdateTime(new Date());
//        userExtensionService.updateBalanceByVersion(userExtension);
        OrderRefundDto orderRefund = orderRefundService.getOrderRefundByRefundSn(eventRefundInfo.getRefundSn());
        if (Objects.isNull(orderRefund)) {
            return;
        }
        RefundInfo refundInfo = refundInfoService.getOne(Wrappers.lambdaQuery(RefundInfo.class).eq(RefundInfo::getRefundId, eventRefundInfo.getRefundSn()));
        if (Objects.equals(refundInfo.getRefundStatus(), RefundStatusEnum.SUCCEED.value())) {
            return;
        }
        refundInfo.setCallbackContent(refundInfo.getCallbackContent());
        refundInfo.setCallbackTime(new Date());
        refundInfo.setRefundStatus(RefundStatusEnum.SUCCEED.value());
        refundInfoService.update(refundInfo, Wrappers.lambdaUpdate(RefundInfo.class).eq(RefundInfo::getRefundId, eventRefundInfo.getRefundSn()));
        orderRefundService.verifyRefund(refundInfo, refundInfo.getPayRefundId());
        // 发送订单退款到余额提醒
//        notifyTemplateService.sendOrderRefundToBalanceNotify(orderRefund,eventRefundInfo.getRefundAmount());
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/CancelOrderListener.java
New file
@@ -0,0 +1,58 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.yami.shop.bean.event.CancelOrderEvent;
import com.yami.shop.bean.order.CancelOrderOrder;
import com.yami.shop.user.common.service.UserScoreLockService;
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;
/**
 * 取消订单事件监听
 * @author yami
 */
@Slf4j
@Component("userCancelOrderListener")
@AllArgsConstructor
public class CancelOrderListener {
    final private UserScoreLockService userScoreLockService;
    /**
     * 取消订单积分抵现花费的积分回退
     */
    @EventListener(CancelOrderEvent.class)
    @Order(CancelOrderOrder.SCORE)
    public void userCancelOrderListener(CancelOrderEvent event) {
        com.yami.shop.bean.model.Order order = event.getOrder();
        userScoreLockService.unlock(order);
//        //如果是积分订单无需
//        // 进行此操作
//        if(Objects.equals(order.getOrderType() , OrderType.SCORE.value())){
//            return;
//        }
//        UserScoreLog userScoreLog = userScoreLogService.getOne(new LambdaQueryWrapper<UserScoreLog>()
//                                                        .eq(UserScoreLog::getBizId, order.getOrderNumber())
//                                                        .eq(UserScoreLog::getUserId,order.getUserId())
//                                                        .eq(UserScoreLog::getIoType,0)
//                                                        .eq(UserScoreLog::getSource,ScoreLogType.SCORE_CASH.value()));
//        //判断此笔订单是否有记录,有进行回退用户积分,并添加日志
//        if(userScoreLog != null){
//            userScoreDetailService.updateLogAndDetail(order.getOrderNumber(),order.getUserId());
//        }
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/CheckIsMainShopListener.java
New file
@@ -0,0 +1,59 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.event.CheckIsMainShopEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.User;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.service.UserService;
import com.yami.shop.user.common.model.UserLevel;
import com.yami.shop.user.common.model.UserLevelRights;
import com.yami.shop.user.common.model.UserRights;
import com.yami.shop.user.common.service.UserLevelRightsService;
import com.yami.shop.user.common.service.UserLevelService;
import com.yami.shop.user.common.service.UserRightsService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
 * 是否自营包邮
 *
 * @author yami
 */
@Slf4j
@Component("defaultCheckIsMainShopListener")
@AllArgsConstructor
public class CheckIsMainShopListener {
    private final UserService userService;
    private final UserLevelService userLevelService;
    private final UserRightsService userRightsService;
    private final UserLevelRightsService userLevelRightsService;
    @EventListener(CheckIsMainShopEvent.class)
    public void checkIsMainShopLister(CheckIsMainShopEvent event) {
        Order orderDb = event.getOrder();
        User user = userService.getUserByUserId(orderDb.getUserId());
        UserLevel userLevel = userLevelService.getOne(new LambdaQueryWrapper<UserLevel>().eq(UserLevel::getLevel, user.getLevel()).eq(UserLevel::getLevelType, user.getLevelType()));
        //todo 自营店包邮是否固定id是2?
        UserRights userRights = userRightsService.getById(2);
        UserLevelRights userLevelRights = userLevelRightsService.getOne(new LambdaQueryWrapper<UserLevelRights>().eq(UserLevelRights::getLevelId, userLevel.getId()).eq(UserLevelRights::getRightsId, userRights.getRightsId()));
        if (Objects.nonNull(userLevelRights)) {
            throw new YamiShopBindException("自营店包邮不能修改运费");
        }
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/OrderRefundListener.java
New file
@@ -0,0 +1,213 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.dto.OrderRefundDto;
import com.yami.shop.bean.enums.ScoreLogType;
import com.yami.shop.bean.event.OrderRefundSuccessEvent;
import com.yami.shop.bean.event.RefundGrowthEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.UserUpdateParam;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.enums.GrowthLogSourceEnum;
import com.yami.shop.user.common.model.UserGrowthLog;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserGrowthLogService;
import com.yami.shop.user.common.service.UserLevelService;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.util.*;
/**
 * 退款订单监听
 * @author lhd
 */
@Component("commentOrderRefundListener")
@AllArgsConstructor
public class OrderRefundListener {
    private final UserExtensionService userExtensionService;
    private final UserScoreLogService userScoreLogService;
    private final UserScoreDetailService userScoreDetailService;
    private final OrderService orderService;
    private final UserGrowthLogService userGrowthLogService;
    private final UserLevelService userLevelService;
    /**
     * 退还用户此笔退款订单使用的积分
     */
    @EventListener(OrderRefundSuccessEvent.class)
    public void userOrderRefundSuccessEvent(OrderRefundSuccessEvent event) {
        OrderRefundDto orderRefundDto = event.getOrderRefundDto();
        //获取退款的所有订单项
        if (CollectionUtils.isEmpty(orderRefundDto.getOrderItems())) {
            return;
        }
        Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, orderRefundDto.getOrderNumber()));
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId,order.getUserId()));
        List<UserScoreLog> scoreLogs = new ArrayList<>();
        List<UserScoreDetail> updateScoreDetails = new ArrayList<>();
        //退还用户此笔退款订单使用的积分,如果有确认收货还需扣减掉获取的积分。
        //先判断当时抵现的积分是否过期,有的话和需要退还的积分进行取小值退还
        int addScore = 0;
        List<UserScoreDetail> scoreDetails = userScoreDetailService.list(new LambdaUpdateWrapper<UserScoreDetail>()
                .eq(UserScoreDetail::getBizId, order.getOrderNumber()).eq(UserScoreDetail::getStatus, 0));
        if(CollectionUtils.isNotEmpty(scoreDetails)) {
            //要修改的用户积分,状态为-1表示还没过期的可以返还的用户积分
            for (UserScoreDetail scoreDetail : scoreDetails) {
                addScore += scoreDetail.getUsableScore();
            }
        }
        List<OrderItem> orderItems = orderRefundDto.getOrderItems();
        long totalScore = 0;
        long totalGainScore = 0;
        for (OrderItem orderItem : orderItems) {
            totalScore += orderItem.getUseScore();
            //确认收货时赠送的积分
            totalGainScore += orderItem.getGainScore() == null?0:orderItem.getGainScore();
        }
        //根据订单需要退还的抵现积分进行取小值
        totalScore = Math.min(addScore,totalScore);
        if(totalScore > 0) {
            //添加积分日志
            UserScoreLog userScoreLog = new UserScoreLog();
            userScoreLog.setUserId(order.getUserId());
            userScoreLog.setScore(totalScore);
            userScoreLog.setBizId(order.getOrderNumber());
            userScoreLog.setSource(ScoreLogType.SCORE_CASH.value());
            userScoreLog.setCreateTime(new Date());
            userScoreLog.setIoType(1);
            scoreLogs.add(userScoreLog);
            userExtension.setScore(userExtension.getScore() + totalScore);
            //积分明细修改、添加明细
            for (UserScoreDetail scoreDetail : scoreDetails) {
                if(totalScore >= scoreDetail.getUsableScore()) {
                    scoreDetail.setStatus(1);
                    updateScoreDetails.add(scoreDetail);
                }else{
                    scoreDetail.setUsableScore(scoreDetail.getUsableScore() - totalScore);
                    updateScoreDetails.add(scoreDetail);
                    UserScoreDetail addDetail = new UserScoreDetail();
                    addDetail.setCreateTime(scoreDetail.getCreateTime());
                    addDetail.setStatus(1);
                    addDetail.setUserId(scoreDetail.getUserId());
                    addDetail.setUsableScore(totalScore);
                    userScoreDetailService.saveUserScoreDetail(addDetail);
                    break;
                }
                totalScore -= scoreDetail.getUsableScore();
                if(totalScore <= 0){
                    break;
                }
            }
        }
        //确认收货后的退款,还需将用户完成此笔订单获取的积分扣除
        if(totalGainScore > 0){
            userExtension.setScore(userExtension.getScore() - totalGainScore);
            receiptRefundScore(order,scoreLogs,updateScoreDetails,totalGainScore);
        }
        //如果不为空则批量保存积分日志
        if(CollectionUtils.isNotEmpty(scoreLogs)){
            userScoreLogService.saveBatch(scoreLogs);
        }
        if(CollectionUtils.isNotEmpty(updateScoreDetails)) {
            userScoreDetailService.updateBatchById(updateScoreDetails);
        }
        userExtensionService.updateById(userExtension);
    }
    /**
     * 退还用户此笔退款订单获得的成长值
     */
    @EventListener(RefundGrowthEvent.class)
    public void refundGrowth(RefundGrowthEvent event) {
        String orderNumber = event.getOrderNumber();
        UserGrowthLog growthLog = userGrowthLogService.getOne(Wrappers.lambdaQuery(UserGrowthLog.class)
                .eq(UserGrowthLog::getBizId, orderNumber)
                .eq(UserGrowthLog::getSource, GrowthLogSourceEnum.ORDER_SUCCESS.value())
        );
        // 如果没有找到这条增加成长值的记录,就不用退成长值了
        if (Objects.isNull(growthLog)) {
            return;
        }
        // 需要减少成长值数值
        Integer growth = growthLog.getChangeGrowth();
        if (Objects.equals(growth, 0)) {
            return;
        }
        String userId = growthLog.getUserId();
        UserUpdateParam param = new UserUpdateParam();
        param.setGrowthValue(-growth);
        param.setBizId(orderNumber);
        param.setGrowthSource(GrowthLogSourceEnum.ORDER_FAIL.value());
        param.setUserIds(Collections.singletonList(userId));
        userLevelService.batchUpdateGrowth(param);
    }
    private void receiptRefundScore(Order order, List<UserScoreLog> scoreLogs,List<UserScoreDetail> updateScoreDetails, Long totalGainScore) {
        List<UserScoreDetail> usableUserScore = userScoreDetailService.list(new LambdaUpdateWrapper<UserScoreDetail>()
                .eq(UserScoreDetail::getStatus, 1)
                .eq(UserScoreDetail::getUserId,order.getUserId())
                .orderByAsc(UserScoreDetail::getCreateTime));
        long sumScore = usableUserScore.stream().mapToLong(UserScoreDetail::getUsableScore).sum();
//        if(totalGainScore > sumScore){
//            // 用户积分不足
//            throw new YamiShopBindException("yami.user.score.enough");
//        }
        //添加积分日志
        UserScoreLog log = new UserScoreLog();
        log.setUserId(order.getUserId());
        log.setScore(totalGainScore);
        log.setBizId(order.getOrderNumber());
        log.setSource(ScoreLogType.SHOP.value());
        log.setCreateTime(new Date());
        log.setIoType(0);
        scoreLogs.add(log);
        // 修改积分明细,如果当前明细不够扣除在进行下一条
        // 如果够添加一条积分明细记录
        for (UserScoreDetail scoreDetail : usableUserScore) {
            if(scoreDetail.getUsableScore() <= totalGainScore){
                scoreDetail.setBizId(order.getOrderNumber());
                scoreDetail.setStatus(0);
                updateScoreDetails.add(scoreDetail);
                totalGainScore -= scoreDetail.getUsableScore();
            }else{
                UserScoreDetail addDetail = new UserScoreDetail();
                addDetail.setBizId(order.getOrderNumber());
                addDetail.setStatus(0);
                addDetail.setCreateTime(scoreDetail.getCreateTime());
                addDetail.setUsableScore(totalGainScore);
                addDetail.setUserId(scoreDetail.getUserId());
                userScoreDetailService.save(addDetail);
                scoreDetail.setUsableScore(scoreDetail.getUsableScore() - totalGainScore);
                updateScoreDetails.add(scoreDetail);
                break;
            }
        }
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/PaySuccessOrderListener.java
New file
@@ -0,0 +1,54 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.yami.shop.bean.event.PaySuccessOrderEvent;
import com.yami.shop.bean.order.PaySuccessOrderOrder;
import com.yami.shop.user.common.dao.UserScoreLockMapper;
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.stream.Collectors;
/**
 * 优惠券
 * @author lanhai
 */
@Component("userPaySuccessListener")
@AllArgsConstructor
public class PaySuccessOrderListener {
    private final UserScoreLockMapper userScoreLockMapper;
    /**
     * 更新积分锁为使用状态
     */
    @EventListener(PaySuccessOrderEvent.class)
    @Order(PaySuccessOrderOrder.COMBO)
    public void userPaySuccessListener(PaySuccessOrderEvent event) {
        List<com.yami.shop.bean.model.Order> orders = event.getOrders();
        List<String> orderNumbers = orders.stream().map(com.yami.shop.bean.model.Order::getOrderNumber).collect(Collectors.toList());
        userScoreLockMapper.unLockByOrderNumbers(1, orderNumbers);
//        for (com.yami.shop.bean.model.Order order : orders) {
//            List<UserScoreLock> userScoreLocks = userScoreLockMapper.listUserScoreLocksByOrderNumber(order.getOrderNumber());
//            if (CollectionUtil.isEmpty(userScoreLocks)) {
//                continue;
//            }
//            List<Long> userScoreLockIds = userScoreLocks.stream().map(UserScoreLock::getId).collect(Collectors.toList());
////            int updateStatus = userScoreLockMapper.unLockByIds(1, userScoreLockIds);
//            if (updateStatus == 0) {
//                throw new YamiShopBindException(ResponseEnum.EXCEPTION);
//            }
//        }
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/ReceiptOrderListener.java
New file
@@ -0,0 +1,179 @@
/*
 * 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.user.common.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.OrderCloseType;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.enums.ReturnMoneyStsType;
import com.yami.shop.bean.event.ReceiptOrderEvent;
import com.yami.shop.bean.model.Category;
import com.yami.shop.bean.model.OrderItem;
import com.yami.shop.bean.model.OrderRefund;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.order.ConfirmOrderOrder;
import com.yami.shop.bean.param.GrowthParamConfig;
import com.yami.shop.bean.param.ProdOrderParam;
import com.yami.shop.bean.param.ScoreConfigParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.util.Arith;
import com.yami.shop.dao.ProductMapper;
import com.yami.shop.dao.UserExtensionMapper;
import com.yami.shop.service.CategoryService;
import com.yami.shop.service.OrderItemService;
import com.yami.shop.service.OrderRefundService;
import com.yami.shop.service.SysConfigService;
import com.yami.shop.user.common.dao.UserLevelMapper;
import com.yami.shop.user.common.model.UserLevel;
import com.yami.shop.user.common.service.UserLevelService;
import com.yami.shop.user.common.util.CategoryScale;
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.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * 确认收货的事件,增加用户成长值和积分
 * @author lhd
 * @date 2020/03/03
 */
@Slf4j
@Component("UserReceiptOrderListener")
@AllArgsConstructor
public class ReceiptOrderListener {
    private final SysConfigService sysConfigService;
    private final UserLevelMapper userLevelMapper;
    private final ProductMapper productMapper;
    private final UserLevelService userLevelService;
    private final OrderRefundService orderRefundService;
    private final OrderItemService orderItemService;
    private final CategoryService categoryService;
    private final UserExtensionMapper userExtensionMapper;
    @EventListener(ReceiptOrderEvent.class)
    @Order(ConfirmOrderOrder.SCORE)
    public void userReceiptOrderLister(ReceiptOrderEvent event) {
        com.yami.shop.bean.model.Order order = event.getOrder();
        //如果订单已经关闭(整单都已经退款了)不需要进行积分、成长值结算
        if(Objects.equals(order.getStatus() , OrderStatus.CLOSE.value()) && Objects.equals(order.getCloseType(), OrderCloseType.REFUND.value())){
            return;
        }
        //如果是积分订单不能获取成长值和积分
        if(Objects.equals(order.getOrderType() , OrderType.SCORE.value())){
            return;
        }
        //判断订单是否有订单项退款成功,如果有减少用户可以获取的部分积分
        List<OrderRefund> orderRefunds = orderRefundService.list(new LambdaQueryWrapper<OrderRefund>()
                .eq(OrderRefund::getOrderId, order.getOrderId()).eq(OrderRefund::getReturnMoneySts, ReturnMoneyStsType.SUCCESS.value()));
        List<Long> orderItemIds = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(orderRefunds)){
            orderRefunds.forEach(refund -> orderItemIds.add(refund.getOrderItemId()));
        }
        // 根据比例取可以获取的积分上限
        List<ProdOrderParam> products = productMapper.getProdsByOrderNumber(order.getOrderNumber());
        // 筛选用户可以获得的订单项积分
        products  = products.stream().filter(prodOrderParam ->orderItemIds.stream().noneMatch(
                orderItemId -> Objects.equals(orderItemId, prodOrderParam.getOrderItemId()))).collect(Collectors.toList());
        //获取积分和成长值获取比例
        ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
        GrowthParamConfig growthParamConfig = sysConfigService.getSysConfigObject(Constant.GROWTH_CONFIG, GrowthParamConfig.class);
        if(Objects.isNull(scoreParam) && Objects.isNull(growthParamConfig)){
            return;
        }
        UserExtension userExtension = userExtensionMapper.selectOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId,order.getUserId()));
        UserLevel nowLevel = userLevelMapper.selectOne(new LambdaQueryWrapper<UserLevel>()
                .eq(UserLevel::getLevel, userExtension.getLevel())
                .eq(UserLevel::getLevelType, userExtension.getLevelType()));
        //初始每笔订单可以获取的成长值
        double growthPrice = growthParamConfig.getBuyOrder();
        long totalScore =0;
        //获取所有分类的比例,并放进map
        List<Category> categories = categoryService.listByShopId(Constant.PLATFORM_SHOP_ID);
        Map<Long, Double> categoryMap = CategoryScale.getScaleByCategory(categories, scoreParam,1);
        //需要批量修改的orderItem
        List<OrderItem> orderItems = new ArrayList<>();
        for (ProdOrderParam product : products) {
            double scoreLimit;
            double score = Arith.div(product.getActualTotal(), scoreParam.getShopGetScore());
            //计算出成长值
            growthPrice += Arith.div(product.getActualTotal(), growthParamConfig.getBuyPrice());
            double getDiscount = Objects.isNull(scoreParam.getGetDiscount()) ? 0.0 : scoreParam.getGetDiscount();
            //判断积分购物获取是全平台还是根据分类上限
            if(scoreParam.getGetDiscountRange() == 0){
                scoreLimit = Arith.div(Arith.mul(product.getActualTotal(), getDiscount), 100);
            }else {
                //查询不到分类比例上限直接下一次循环
                if(!categoryMap.containsKey(product.getCategoryId())) {
                    continue;
                }
                scoreLimit = Arith.div(Arith.mul(product.getActualTotal(), categoryMap.get(product.getCategoryId())), 100);
            }
            scoreLimit = Arith.div(scoreLimit, scoreParam.getShopGetScore());
            //上限取最小值
            score = Math.min(score, scoreLimit);
            //根据用户等级获取积分倍数
            if(nowLevel != null && nowLevel.getRateScore() != null && nowLevel.getRateScore() > 1){
                score = Arith.mul(score ,nowLevel.getRateScore());
            }
            long gainScore = (long) score;
            // 如果积分获取开关关闭了,则无法获取积分
            if(Objects.isNull(scoreParam.getShopScoreSwitch()) || !scoreParam.getShopScoreSwitch()){
                gainScore = 0;
            }
            if(gainScore <= 0){
                continue;
            }
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderItemId(product.getOrderItemId());
            orderItem.setGainScore(gainScore);
            orderItems.add(orderItem);
            totalScore += gainScore;
        }
        // 如果积分获取开关关闭了,则无法获取积分
        if(Objects.isNull(scoreParam.getShopScoreSwitch()) || !scoreParam.getShopScoreSwitch()){
            totalScore = 0;
        }
        // 如果成长值获取开关关闭了,则无法获取成长值
        if(Objects.isNull(growthParamConfig.getShopGrowthSwitch()) || !growthParamConfig.getShopGrowthSwitch()){
            growthPrice = 0;
        }
        if(CollectionUtils.isNotEmpty(orderItems) && totalScore > 0){
            orderItemService.updateBatchById(orderItems);
        }
        // 成长值和积分大于0 增加用户成长值和积分
        if(growthPrice > 0 || totalScore > 0) {
            userLevelService.addGrowthAndScore(growthPrice, totalScore, order.getUserId(),order.getOrderNumber(), userExtension,1);
        }
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/UserDataListener.java
New file
@@ -0,0 +1,84 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.yami.shop.bean.event.UserDataEvent;
import com.yami.shop.bean.order.UserDataOrder;
import com.yami.shop.bean.param.UserManagerParam;
import com.yami.shop.common.util.Arith;
import com.yami.shop.user.common.dao.UserBalanceLogMapper;
import com.yami.shop.user.common.dao.UserScoreLogMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;
/**
 * 统计一下用户的信息
 * @author yami
 */
@Slf4j
@Component("UserDataListener")
@AllArgsConstructor
public class UserDataListener {
    private final UserScoreLogMapper userScoreLogMapper;
    private final UserBalanceLogMapper userBalanceLogMapper;
    @EventListener(UserDataEvent.class)
    @Order(UserDataOrder.USER)
    public void userReceiptOrderLister(UserDataEvent event) {
        UserManagerParam param = event.getUserManagerParam();
        String userId = param.getUserId();
        if (StrUtil.isBlank(userId)){
            return;
        }
        // 累计积分
        Integer sumScore = 0;
        try {
            sumScore = userScoreLogMapper.countSumScore(userId);
        } catch (DataIntegrityViolationException e) {
            //如果数值过大,设一个默认值
            sumScore=99999999;
        }
        param.setSumScore(Objects.nonNull(sumScore) ? sumScore : 0);
        // 获取最新充值时间
        Date date = userBalanceLogMapper.getRecentRechargeTime(userId);
        Date reConsTime = param.getReConsTime();
        if (Objects.isNull(reConsTime)) {
            param.setReConsTime(date);
        } else if (Objects.nonNull(date)){
            param.setReConsTime(DateUtil.compare(reConsTime, date)>0?reConsTime: date);
        }
        // 充值余额
        Double rechargeAmount = userBalanceLogMapper.countUserRechargeAmount(userId);
        param.setRechargeAmount(Objects.nonNull(rechargeAmount)?rechargeAmount: 0.0);
        // 充值次数
        param.setRechargeTimes(userBalanceLogMapper.countUserRechargeNum(userId));
        // 实付金额, 累计支付的金额: 除了余额支付/积分支付的订单累计金额 + 余额充值金额
        param.setActualAmount(sum(param.getActualAmount(),param.getRechargeAmount()));
    }
    private Double sum(Double a,Double b) {
        if (Objects.isNull(a) || Objects.isNull(b)) {
            return  0.0;
        }
        return Arith.add(a,b);
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/UserDestroyListener.java
New file
@@ -0,0 +1,80 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.ScoreLogType;
import com.yami.shop.bean.event.UserDestroyEvent;
import com.yami.shop.bean.event.UserRegisterLogEvent;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.bean.model.UserCollection;
import com.yami.shop.bean.model.UserCollectionShop;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.ScoreConfigParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.security.common.dao.AppConnectMapper;
import com.yami.shop.security.common.enums.SysTypeEnum;
import com.yami.shop.security.common.manager.TokenStore;
import com.yami.shop.security.common.model.AppConnect;
import com.yami.shop.security.common.service.AppConnectService;
import com.yami.shop.service.*;
import com.yami.shop.user.common.enums.GrowthLogSourceEnum;
import com.yami.shop.user.common.model.*;
import com.yami.shop.user.common.service.*;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author chiley
 * @date 2022/9/8 11:11
 */
@Slf4j
@Component("userDestroyListener")
@AllArgsConstructor
public class UserDestroyListener {
    private UserAddrService userAddrService;
    private UserGrowthLogService userGrowthLogService;
    private UserScoreDetailService userScoreDetailService;
    private UserScoreLockService userScoreLockService;
    private UserScoreLogService userScoreLogService;
    private UserTagUserService userTagUserService;
    private AppConnectService appConnectService;
    private TokenStore tokenStore;
    private final AppConnectMapper appConnectMapper;
    /**
     * 用户注销时,删除相关数据
     */
    @EventListener(UserDestroyEvent.class)
    public void userDestroyListener(UserDestroyEvent event) {
        String userId = event.getUserId();
        userAddrService.remove(new LambdaQueryWrapper<UserAddr>().eq(UserAddr::getUserId, userId));
        userGrowthLogService.remove(new LambdaQueryWrapper<UserGrowthLog>().eq(UserGrowthLog::getUserId, userId));
        userScoreDetailService.remove(new LambdaQueryWrapper<UserScoreDetail>().eq(UserScoreDetail::getUserId, userId));
        userScoreLockService.remove(new LambdaQueryWrapper<UserScoreLock>().eq(UserScoreLock::getUserId, userId));
        userScoreLogService.remove(new LambdaQueryWrapper<UserScoreLog>().eq(UserScoreLog::getUserId, userId));
        userTagUserService.remove(new LambdaQueryWrapper<UserTagUser>().eq(UserTagUser::getUserId, userId));
        appConnectService.remove(new LambdaQueryWrapper<AppConnect>().eq(AppConnect::getUserId, userId));
        tokenStore.deleteAllToken(SysTypeEnum.ORDINARY.value().toString(), userId);
        // 解除社交账号的绑定
        appConnectMapper.unBindUserByUserId(userId);
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/listener/UserRegisterLogListener.java
New file
@@ -0,0 +1,174 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.listener;
import com.yami.shop.bean.enums.ScoreLogType;
import com.yami.shop.bean.event.UserRegisterLogEvent;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.ScoreConfigParam;
import com.yami.shop.common.config.Constant;
import com.yami.shop.service.SysConfigService;
import com.yami.shop.service.UserExtensionService;
import com.yami.shop.user.common.enums.GrowthLogSourceEnum;
import com.yami.shop.user.common.model.UserBalanceLog;
import com.yami.shop.user.common.model.UserGrowthLog;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.UserBalanceLogService;
import com.yami.shop.user.common.service.UserGrowthLogService;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author: cl
 * @date: 2021-04-21 11:09:06
 */
@Slf4j
@Component("userRegisterLogListener")
@AllArgsConstructor
public class UserRegisterLogListener {
    private final UserScoreDetailService userScoreDetailService;
    private final UserScoreLogService userScoreLogService;
    private final UserBalanceLogService userBalanceLogService;
    private final UserGrowthLogService userGrowthLogService;
    private final SysConfigService sysConfigService;
    private final UserExtensionService userExtensionService;
    /**
     * 用户注册时,初始化 积分 余额 成长值 用户等级 添加日志
     */
    @EventListener(UserRegisterLogEvent.class)
    public void userRegisterLogListener(UserRegisterLogEvent event) {
        List<UserExtension> userExtensions = event.getUserExtensions();
        if (CollectionUtils.isEmpty(userExtensions)) {
            return;
        }
        // 积分日志
        List<UserScoreLog> scoreLogs = new ArrayList<>();
        // 积分明细
        List<UserScoreDetail> scoreDetails = new ArrayList<>();
        // 用户余额
        List<UserBalanceLog> userBalanceLogs = new ArrayList<>();
        // 成长值
        List<UserGrowthLog> growthLogs = new ArrayList<>();
        Date now = new Date();
        for (UserExtension userExtension : userExtensions) {
            String userId = userExtension.getUserId();
            // 注册增送积分
            ScoreConfigParam scoreParam = sysConfigService.getSysConfigObject(Constant.SCORE_CONFIG, ScoreConfigParam.class);
            // 更新积分
            userExtension.setScore(scoreParam.getRegisterScore() + userExtension.getScore());
            setRegisterScoreLog(scoreLogs, scoreDetails, userExtension, scoreParam);
            // 积分log
            Long score = Objects.isNull(scoreParam.getRegisterScore()) ? userExtension.getScore() : userExtension.getScore() - scoreParam.getRegisterScore();
            setSystemScoreLog(scoreLogs, scoreDetails, now, userId, score);
            // 余额
            Double balance = userExtension.getBalance();
            setBalanceLog(userBalanceLogs, now, userId, balance);
            // 成长值
            Integer growth = userExtension.getGrowth();
            setGrowthLog(growthLogs, now, userId, growth);
        }
        userExtensionService.updateBatchById(userExtensions);
        if (CollectionUtils.isNotEmpty(scoreLogs)) {
            userScoreLogService.saveBatch(scoreLogs);
        }
        if (CollectionUtils.isNotEmpty(scoreDetails)) {
            userScoreDetailService.saveBatch(scoreDetails);
        }
        if (CollectionUtils.isNotEmpty(userBalanceLogs)) {
            userBalanceLogService.saveBatch(userBalanceLogs);
        }
        if (CollectionUtils.isNotEmpty(growthLogs)) {
            userGrowthLogService.saveBatch(growthLogs);
        }
    }
    private void setGrowthLog(List<UserGrowthLog> growthLogs, Date now, String userId, Integer growth) {
        if (Objects.nonNull(growth) && growth > 0) {
            UserGrowthLog growthLog = new UserGrowthLog();
            growthLog.setUserId(userId);
            growthLog.setSource(GrowthLogSourceEnum.SYSTEM.value());
            growthLog.setChangeGrowth(growth);
            growthLog.setCreateTime(now);
            growthLog.setRemarks("系统修改用户成长值");
            growthLogs.add(growthLog);
        }
    }
    private void setBalanceLog(List<UserBalanceLog> userBalanceLogs, Date now, String userId, Double balance) {
        if (Objects.nonNull(balance) && balance > 0) {
            UserBalanceLog userBalanceLog = new UserBalanceLog();
            userBalanceLog.setUserId(userId);
            userBalanceLog.setCreateTime(now);
            userBalanceLog.setChangeBalance(balance);
            userBalanceLog.setIoType(1);
            // 平台修改余额
            userBalanceLog.setType(5);
            userBalanceLogs.add(userBalanceLog);
        }
    }
    private void setSystemScoreLog(List<UserScoreLog> scoreLogs, List<UserScoreDetail> scoreDetails, Date now, String userId, Long score) {
        if (score > 0) {
            UserScoreLog userScoreLog = new UserScoreLog();
            userScoreLog.setUserId(userId);
            userScoreLog.setScore(score);
            // 用户批量导入注册设置积分
            userScoreLog.setSource(ScoreLogType.SYSTEM.value());
            userScoreLog.setCreateTime(now);
            userScoreLog.setIoType(1);
            scoreLogs.add(userScoreLog);
            // 积分明细
            UserScoreDetail addDetail = new UserScoreDetail();
            addDetail.setStatus(1);
            addDetail.setUserId(userId);
            addDetail.setCreateTime(now);
            addDetail.setUsableScore(score);
            scoreDetails.add(addDetail);
        }
    }
    private void setRegisterScoreLog(List<UserScoreLog> scoreLogs, List<UserScoreDetail> scoreDetails, UserExtension userExtension, ScoreConfigParam scoreParam) {
        if(scoreParam.getRegisterScore() != null) {
            //添加积分明细
            UserScoreDetail addDetail = new UserScoreDetail();
            addDetail.setCreateTime(new Date());
            addDetail.setStatus(1);
            addDetail.setUserId(userExtension.getUserId());
            addDetail.setUsableScore(scoreParam.getRegisterScore());
            scoreDetails.add(addDetail);
            //添加积分日志
            UserScoreLog userScoreLog = new UserScoreLog();
            userScoreLog.setUserId(userExtension.getUserId());
            userScoreLog.setScore(scoreParam.getRegisterScore());
            userScoreLog.setSource(ScoreLogType.REGISTER.value());
            userScoreLog.setCreateTime(new Date());
            userScoreLog.setIoType(1);
            scoreLogs.add(userScoreLog);
        }
    }
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/Coupon.java
New file
@@ -0,0 +1,113 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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 org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 * @author yami
 */
@Data
@TableName("tz_coupon")
public class Coupon implements Serializable {
    private static final long serialVersionUID = 8018312153820119913L;
    @TableId
    @Schema(description = "优惠券id" )
    private Long couponId;
    @Schema(description = "店铺ID" )
    private Long shopId;
    @Schema(description = "优惠券名称" )
    private String couponName;
    @Schema(description = "副标题" )
    private String subTitle;
    @Schema(description = "优惠类型 1:代金券 2:折扣券 3:兑换券" )
    private Integer couponType;
    @Schema(description = "使用条件" )
    private Double cashCondition;
    @Schema(description = "减免金额" )
    private Double reduceAmount;
    @Schema(description = "折扣额度" )
    private Double couponDiscount;
    @Schema(description = "生效类型 1:固定时间 2:领取后生效" )
    private Integer validTimeType;
    @Schema(description = "投放时间" )
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date launchTime;
    @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 = "领券后X天起生效" )
    private Integer afterReceiveDays;
    @Schema(description = "有效天数" )
    private Integer validDays;
    @Schema(description = "库存" )
    private Integer stocks;
    @Schema(description = "原始库存" )
    private Integer sourceStock;
    @Schema(description = "适用商品类型 0全部商品参与 1指定商品参与 2指定商品不参与" )
    private Integer suitableProdType;
    @Schema(description = "每个用户领券上限,如不填则默认为1" )
    private Integer limitNum;
    @Schema(description = "版本号" )
    private Integer version;
    @Schema(description = "是否积分优惠券 0不是 1是" )
    private Integer isScoreType;
    @Schema(description = "积分价格" )
    private Integer scorePrice;
    @Schema(description = "优惠券过期状态 0:过期 1:未过期" )
    private Integer overdueStatus;
    @Schema(description = "优惠券投放状态 0:未投放 1:投放 -1取消投放" )
    private Integer putonStatus;
    @Schema(description = "优惠券所在的店铺" )
    @TableField(exist = false)
    private String shopName;
    @Schema(description = "优惠券数量" )
    @TableField(exist = false)
    private Integer couponNum;
    @Schema(description = "获取方式  0=客户领取 1=平台发放" )
    private Integer getWay;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserBalance.java
New file
@@ -0,0 +1,68 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * 余额充值级别表
 *
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
@Data
@TableName("tz_user_balance")
public class UserBalance implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId
    private Long balanceId;
    /**
     * 充值余额标题
     */
    private String balanceTitle;
    /**
     * 充值金额
     */
    private Double rechargeAmount;
    /**
     * 背景图片
     */
    private String img;
    /**
     * 赠送金额
     */
    private Double presAmount;
    /**
     * 赠送积分
     */
    private Long presScore;
    /**
     * 赠送成长值
     */
    private Integer presGrowth;
    /**
     * 顺序
     */
    private Integer seq;
    @TableField(exist = false)
    private List<Coupon> couponList;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserBalanceCoupon.java
New file
@@ -0,0 +1,45 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
 *
 *
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tz_user_balance_coupon")
public class UserBalanceCoupon implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 余额充值优惠券关联id
     */
    private Long balanceId;
    /**
     * 优惠券id
     */
    private Long couponId;
    /**
     * 优惠券数量
     */
    private Integer couponNum;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserBalanceLog.java
New file
@@ -0,0 +1,73 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * 余额充值记录
 *
 * @author YXF
 * @date 2020-09-09 17:38:30
 */
@Data
@TableName("tz_user_balance_log")
public class UserBalanceLog implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 充值记录id
     */
    @TableId
    private Long balanceLogId;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 改变余额
     */
    private Double changeBalance;
    /**
     * 收支类型 0支出 1收入
     */
    private Integer ioType;
    /**
     * 支付单号
     */
    private String payNo;
    /**
     * 1:充值 2:赠送 3:支付 4:退款 5平台手动修改 6.充值会员
     */
    private Integer type;
    /**
     * 是否支付1已支付0未支付
     */
    private Integer isPayed;
    /**
     * 充值余额id
     */
    private Long balanceId;
    /**
     * 退款单号
     */
    private String refundSn;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserGrowthLog.java
New file
@@ -0,0 +1,72 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * 用户成长值记录
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_growth_log")
public class UserGrowthLog implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 成长值获取记录表
     */
    @TableId
    private Long logId;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 来源 0:系统修改 1:订单支付 2:订单退款 3:余额充值
     */
    private Integer source;
    /**
     * 关联业务id
     */
    private String bizId;
    /**
     * 变更成长值
     */
    private Integer changeGrowth;
    /**
     * 备注
     */
    private String remarks;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 用户昵称
     */
    @TableField(exist = false)
    private String nickName;
    /**
     * 订单编号
     */
    @TableField(exist = false)
    private  String orderNumber;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevel.java
New file
@@ -0,0 +1,125 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_level")
public class UserLevel implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId
    private Long id;
    /**
     * 等级
     */
    private Integer level;
    /**
     * 等级名称
     */
    private String levelName;
    /**
     * 等级条件 0 普通会员 1 付费会员
     */
    private Integer levelType;
    /**
     * 所需成长值
     */
    private Integer needGrowth;
    /**
     * 付费会员价格
     */
    private Double needAmount;
    /**
     * 有效期(天)
     */
    private Integer term;
    /**
     * 期数类型
     */
    private Integer termType;
    /**
     * 背景图片
     */
    private String img;
    /**
     * 折扣范围 0 全平台 1 自营店
     */
    private Integer discountRange;
    /**
     * 折扣方式 0 全部商品 1 分类下的商品
     */
    private Integer discountType;
    /**
     * 会员折扣
     */
    private Double discount;
    /**
     * 赠送积分
     */
    private Long presScore;
    /**
     * 积分回馈倍率
     */
    private Double rateScore;
    /**
     * 是否包邮 0:不包邮 1:包邮
     */
    private Integer isFreeFee;
    /**
     * 1:已更新 0:停用 -1:未更新(等级修改后,用户等级的更新)
     */
    private Integer status;
    /**
     * 优惠券列表
     */
    @TableField(exist = false)
    private List<Coupon> couponList;
    @TableField(exist = false)
    private List<Long> couponIds;
    /**
     * 等级分类列表
     */
    @TableField(exist = false)
    private List<Long> categoryIds;
    @TableField(exist = false)
    private List<Long> categorys;
    /**
     *  权益id数组
     */
    @TableField(exist = false)
    private List<Long> userRightsIds;
    /**
     *  权益数组
     */
    @TableField(exist = false)
    private List<UserRights> userRights;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelCategory.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 *
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_level_category")
public class UserLevelCategory implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 用户等级分类关联id
     */
    @TableId
    private Long userLevelCategoryId;
    /**
     * 等级id
     */
    private Long levelId;
    /**
     * 分类id
     */
    private Long categoryId;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelCoupon.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 *
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_level_coupon")
public class UserLevelCoupon implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 用户等级优惠券关联id
     */
    @TableId
    private Long userLevelCouponId;
    /**
     * 等级id
     */
    private Long levelId;
    /**
     * 优惠券id
     */
    private Long couponId;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelLog.java
New file
@@ -0,0 +1,114 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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 org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
/**
 *
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_level_log")
public class UserLevelLog implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId
    @Schema(description = "等级记录表" )
    private Long levelLogId;
    @Schema(description = "用户id" )
    private String userId;
    @Schema(description = "用户头像" )
    @TableField(exist = false)
    private String pic;
    @Schema(description = "用户名" )
    @TableField(exist = false)
    private String userName;
    @Schema(description = "用户名称" )
    @TableField(exist = false)
    private String nickName;
    @Schema(description = "升级之后的等级" )
    private Integer level;
    @Schema(description = "等级名称" )
    private String levelName;
    @Schema(description = "等级类型 0 普通会员 1 付费会员" )
    private Integer levelType;
    @Schema(description = "升级时间" )
    private Date createTime;
    @Schema(description = "起始时间" )
    @TableField(exist = false)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createStartTime;
    @Schema(description = "结束时间" )
    @TableField(exist = false)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createEndTime;
    @Schema(description = "礼物发放状态(0发送中 1发送已完成)" )
    private Integer state;
    @Schema(description = "礼物发放时间" )
    private Date giftTime;
    @Schema(description = "快递方式" )
    private Long devId;
    @Schema(description = "快递公司" )
    @TableField(exist = false)
    private String dvyName;
    @Schema(description = "物流编号" )
    private String devNo;
    @Schema(description = "订单收货地址id" )
    private Long addrOrderId;
    @Schema(description = "支付单号" )
    private String payNo;
    @Schema(description = "是否支付1已支付0未支付" )
    private Integer isPayed;
    @Schema(description = "支付方式" )
    private Integer payType;
    @Schema(description = "支付金额" )
    private Double payAmount;
    @Schema(description = "有效期数" )
    private Integer term;
    @Schema(description = "期数类型 1:日 2:周 3:月 4:季 5:年" )
    private Integer termType;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserLevelRights.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_level_rights")
public class UserLevelRights implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 等级-权益关联id
     */
    @TableId
    private Long levelRightsId;
    /**
     * 等级id
     */
    private Long levelId;
    /**
     * 权益id
     */
    private Long rightsId;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserRights.java
New file
@@ -0,0 +1,54 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_rights")
public class UserRights implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId
    @Schema(description = "权益id" )
    private Long rightsId;
    @Schema(description = "权益名称" )
    private String rightsName;
    @Schema(description = "权益图标" )
    private String icon;
    @Schema(description = "权益简介" )
    private String description;
    @Schema(description = "0系统核销 1商家线下核销" )
    private Integer serviceType;
    @Schema(description = "状态:-1:禁用 1:正常(仅用于系统核销)" )
    private Integer status;
    @Schema(description = "顺序" )
    private Integer seq;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserScoreDetail.java
New file
@@ -0,0 +1,64 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 *
 *
 * @author lhd
 * @date 2020-05-25 15:31:02
 */
@Data
@TableName("tz_user_score_detail")
public class UserScoreDetail implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 积分明细表
     */
    @TableId
    private Long userScoreDetailId;
    /**
     * 可用积分
     */
    private Long usableScore;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 业务id
     */
    private String bizId;
    /**
     * 获取时间
     */
    private Date createTime;
    /**
     * 更新时间
     */
    private Date updateTime;
    /**
     * 过期时间
     */
    private Date expireTime;
    /**
     * 状态  -1过期 0订单抵现 1正常
     */
    private Integer status;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserScoreLock.java
New file
@@ -0,0 +1,48 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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 lhd
 * @date 2022-05-06 17:27:53
 */
@Data
@TableName("tz_user_score_lock")
@Schema(description = "积分锁定信息")
public class UserScoreLock implements Serializable{
    private static final long serialVersionUID = 1L;
    @TableId
    private Long id;
    @Schema(description = "创建时间" )
    private Date createTime;
    @Schema(description = "更新时间" )
    private Date updateTime;
    @Schema(description = "用户id" )
    private String userId;
    @Schema(description = "订单号" )
    private String orderNumber;
    @Schema(description = "状态-1已解锁 0待确定 1已锁定" )
    private Integer status;
    @Schema(description = "锁定积分数量" )
    private Long score;
    @Schema(description = "变动的积分id集合" )
    private String scoreGetLogIds;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserScoreLog.java
New file
@@ -0,0 +1,83 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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 2020-02-26 16:03:14
 */
@Data
@TableName("tz_user_score_log")
public class UserScoreLog implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 日志id
     */
    @TableId
    private Long logId;
    /**
     * 用户id
     */
    private String userId;
    /**
     * 来源 1 订单 2 等级提升获取 3 签到  4 购物抵扣积分 5 积分过期
     */
    @Schema(description = "来源 0.注册送积分 1 订单 2 等级提升获取 3 任务  4 购物抵扣积分 5 积分过期  6 开店交保障金加积分" )
    private Integer source;
    /**
     * 业务id
     */
    @Schema(description = "业务id" )
    private String bizId;
    /**
     * 获取积分数量
     */
    @Schema(description = "获取积分数量" )
    private Long score;
    /**
     * 出入类型 0=支出 1=收入
     */
    @Schema(description = "出入类型 0=支出 1=收入" )
    private Integer ioType;
    /**
     * 创建时间
     */
    @Schema(description = "创建时间" )
    private Date createTime;
    /**
     * 用户昵称
     */
    @TableField(exist = false)
    private String nickName;
    /**
     * 订单编号
     */
    @TableField(exist = false)
    private String orderNumber;
    /**
     * 积分是否锁定
     */
    @TableField(exist = false)
    private Integer isLock;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserTag.java
New file
@@ -0,0 +1,153 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
 * 客户标签
 *
 * @author LGH
 * @date 2020-09-09 15:40:59
 */
@Data
@TableName("tz_user_tag")
public class UserTag implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 自增id
     */
    @TableId
    private Long userTagId;
    /**
     * 标签名字
     */
    private String tagName;
    /**
     * 标签类型0手动1条件2系统
     */
    private Integer tagType;
    /**
     * 系统标签是否开启
     */
    private Integer isSysTurnOn;
    /**
     * 成为客户开始时间
     */
    private LocalDateTime registerMinTime;
    /**
     * 成为客户结束时间
     */
    private LocalDateTime registerMaxTime;
    /**
     * 关注开始时间
     */
    private LocalDateTime subscribeMinTime;
    /**
     * 关注结束时间
     */
    private LocalDateTime subscribeMaxTime;
    /**
     * 成为会员开始时间
     */
    private LocalDateTime toBeMemberMinTime;
    /**
     * 成为会员结束时间
     */
    private LocalDateTime toBeMemberMaxTime;
    /**
     * 最近消费时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    private Integer recentPurchaseTime;
    /**
     * 消费次数时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    private Integer purchaseNumTime;
    /**
     * 消费次数最小次数
     */
    private Long purchaseNumMinNum;
    /**
     * 消费次数最大次数
     */
    private Long purchaseNumMaxNum;
    /**
     * 消费金额时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    private Integer purchaseAmountTime;
    /**
     * 消费金额最小金额
     */
    private BigDecimal purchaseAmountMinAmount;
    /**
     * 消费金额最大金额
     */
    private BigDecimal purchaseAmountMaxAmount;
    /**
     * 订单均价时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    private Integer orderAveragePriceTime;
    /**
     * 订单均价最小金额
     */
    private BigDecimal orderAveragePriceMinAmount;
    /**
     * 订单均价最大金额
     */
    private BigDecimal orderAveragePriceMaxAmount;
    /**
     * 充值金额时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    private Integer rechargeAmountTime;
    /**
     * 充值金额最小金额
     */
    private BigDecimal rechargeAmountMinAmount;
    /**
     * 充值金额最大金额
     */
    private BigDecimal rechargeAmountMaxAmount;
    /**
     * 充值次数时间范围0(不限)1(今天)2(最近7天)3(最近15天)4(最近30天)5(最近45天)6(最近60天)7(最近90天)8(最近180天)
     */
    private Integer rechargeNumTime;
    /**
     * 充值次数最小次数
     */
    private Long rechargeNumMinNum;
    /**
     * 充值次数最大次数
     */
    private Long rechargeNumMaxNum;
    /**
     * 符合标签的人数
     */
    private Long userNum;
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
    /**
     * 统计更新时间
     */
    private LocalDateTime statisticUpdateTime;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/model/UserTagUser.java
New file
@@ -0,0 +1,43 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.model;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
 * 用户和标签关联表
 *
 * @author LGH
 * @date 2020-09-10 08:44:22
 */
@Data
@TableName("tz_user_tag_user")
public class UserTagUser implements Serializable{
    private static final long serialVersionUID = 1L;
    /**
     * 自增id
     */
    @TableId
    private Long userTagUserId;
    /**
     * 标签id
     */
    private Long userTagId;
    /**
     * 用户id
     */
    private String userId;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/ScoreOrderService.java
New file
@@ -0,0 +1,56 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.model.Order;
import com.yami.shop.user.common.dto.ScoreOrderMergerDto;
/**
 * @author LGH
 * @date 2019-08-27 17:55:57
 */
public interface ScoreOrderService extends IService<Order> {
    /**
     * 将确认订单的信息放入缓存
     *
     * @param userId 用户id
     * @param scoreOrderMergerDto 积分订单数据
     * @return 积分订单数据
     */
    ScoreOrderMergerDto putConfirmScoreOrderCache(String userId, ScoreOrderMergerDto scoreOrderMergerDto);
    /**
     * 获取缓存中确认订单的信息
     * @param userId 用户id
     * @return 确认订单的信息
     */
    ScoreOrderMergerDto getConfirmScoreOrderCache(String userId);
    /**
     * 移除缓存中确认订单的信息
     *
     * @param userId 用户id
     */
    void removeConfirmScoreOrderCache(String userId);
    /**
     * 提交订单
     *
     * @param userId 用户id
     * @param hadConfirmOrder 提交积分订单信息
     * @return 处理后的订单信息
     */
    Order submit(String userId, ScoreOrderMergerDto hadConfirmOrder);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserBalanceCouponService.java
New file
@@ -0,0 +1,60 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.user.common.model.Coupon;
import com.yami.shop.user.common.model.UserBalanceCoupon;
import java.util.List;
import java.util.Set;
/**
 *
 *
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
public interface UserBalanceCouponService extends IService<UserBalanceCoupon> {
    /**
     * 批量插入
     *
     * @param balanceId 充值余额id
     * @param couponList 优惠券列表
     */
    void insertBatch(Long balanceId, List<Coupon> couponList);
    /**
     * 删除余额、优惠券关联信息
     *
     * @param balanceId  充值余额id
     * @param couponIdSet 优惠券id列表
     */
    void removeByBalaceIdAndCouponId(Long balanceId, Set<Long> couponIdSet);
    /**
     * 批量更新余额优惠券关联信息
     *
     * @param balanceId  充值余额id
     * @param couponList 优惠券列表
     */
    void updateBatchByCoupons(Long balanceId, List<Coupon> couponList);
    /**
     * 删除余额、优惠券关联信息
     *
     * @param balanceId 充值余额id
     */
    void removeByBalanceId(Long balanceId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserBalanceLogService.java
New file
@@ -0,0 +1,40 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.user.common.dto.UserBalanceLogDto;
import com.yami.shop.user.common.model.UserBalanceLog;
/**
 * 余额充值记录
 *
 * @author YXF
 * @date 2020-09-09 17:38:30
 */
public interface UserBalanceLogService extends IService<UserBalanceLog> {
    /**
     * 分页获取余额充值记录
     * @param page 分页信息
     * @param userId 用户id
     * @return
     */
    PageParam<UserBalanceLogDto> getLogPage(PageParam<UserBalanceLogDto> page, String userId);
    /**
     * 获取用户最新充值余额的记录
     * @param userId
     * @return
     */
    UserBalanceLog getMaxCrtTimeByUserId(String userId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserBalanceService.java
New file
@@ -0,0 +1,94 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.param.UserUpdateParam;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.user.common.model.UserBalance;
import com.yami.shop.user.common.model.UserBalanceLog;
import java.util.List;
/**
 * 余额充值级别表
 *
 * @author YXF
 * @date 2020-09-08 10:42:39
 */
public interface UserBalanceService extends IService<UserBalance> {
    /**
     * 保存余额充值模板
     * @param userBalance 余额充值模板
     */
    void saveBalance(UserBalance userBalance);
    /**
     * 更新余额充值模板
     * @param userBalance 余额充值模板
     */
    void updateBalanceById(UserBalance userBalance);
    /**
     * 获取余额充值模板信息
     * @param balanceId 余额充值模板id
     * @return 余额充值模板信息
     */
    UserBalance getBalanceInfo(Long balanceId);
    /**
     * 清除缓存
     */
    void removeCacheByBalanceId();
    /**
     * 获取余额充值模板列表
     * @return 余额充值模板列表
     */
    List<UserBalance> getBalanceList();
    /**
     * 余额充值回调
     * @param payInfoResultBO
     * @param payInfo
     * @return
     */
    ServerResponseEntity<String> noticeRecharge(PayInfoResultBO payInfoResultBO, PayInfo payInfo);
    /**
     * 余额充值支付成功处理
     * @param payNo 支付单号
     * @param userBalanceLog
     * @param payInfoResultBO
     */
    void paySuccess(String payNo, UserBalanceLog userBalanceLog, PayInfoResultBO payInfoResultBO);
    /**
     *批量给用户充值余额
     * @param param 用户余额更新数据
     * @return 是否充值成功
     */
    Boolean batchUpdateUserBalance(UserUpdateParam param);
    /**
     * 分页获取用户余额充值记录列表
     * @param page 分页信息
     * @param userId 用户id
     * @return 用户余额充值记录列表
     */
    IPage<UserBalanceLog> getPageByUserId(PageParam<UserBalanceLog> page, String userId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserGrowthLogService.java
New file
@@ -0,0 +1,41 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.user.common.model.UserGrowthLog;
/**
 * 用户成长值记录
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserGrowthLogService extends IService<UserGrowthLog> {
    /**
     * 分页获取用户成长值记录
     * @param page 分页信息
     * @param userGrowthLog 筛选条件
     * @return 用户成长值记录列表
     */
    Page<UserGrowthLog> getPage(PageParam<UserGrowthLog> page, UserGrowthLog userGrowthLog);
    /**
     * 根据用户id,获取用户成长值记录列表
     * @param page 分页信息
     * @param userId 用户id
     * @return 列表
     */
    IPage<UserGrowthLog> getPageByUserId(PageParam<UserGrowthLog> page, String userId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelCategoryService.java
New file
@@ -0,0 +1,45 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.user.common.model.UserLevelCategory;
import java.util.List;
/**
 * 等级分类关联
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelCategoryService extends IService<UserLevelCategory> {
    /**
     * 根据等级id,获取等级关联的分类id列表
     * @param id 等级id
     * @return 分类id列表
     */
    List<Long> getCategoryIdByLevelId(Long id);
    /**
     * 批量保存等级分类关联信息
     * @param categorys 分类id列表
     * @param id 等级id
     */
    void insertBatch(Long[] categorys,Long id);
    /**
     * 批量删除等级分类关联信息
     * @param categorys 分类id列表
     * @param id 等级id
     */
    void delBatch(Long[] categorys, Long id);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelCouponService.java
New file
@@ -0,0 +1,46 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.user.common.model.Coupon;
import com.yami.shop.user.common.model.UserLevelCoupon;
import java.util.List;
/**
 *
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelCouponService extends IService<UserLevelCoupon> {
    /**
     * 批量插入等级优惠券关联信息
     * @param coupons 优惠券id列表
     * @param id 等级id
     */
    void insertBatchCoupon(Long[] coupons, Long id);
    /**
     * 批量删除等级优惠券关联信息
     * @param coupons 优惠券id列表
     * @param id 等级id
     */
    void delBatchCoupon(Long[] coupons, Long id);
    /**
     * 根据等级id,获取优惠券列表信息
     * @param id 等级id
     * @return 优惠券列表
     */
    List<Coupon> getCouponListByLevelId(Long id);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelLogService.java
New file
@@ -0,0 +1,64 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.param.CustomerMemberParam;
import com.yami.shop.bean.param.CustomerReqParam;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.user.common.model.UserLevelLog;
/**
 *
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelLogService extends IService<UserLevelLog> {
    /**
     * 分页获取用户等级记录
     * @param page 分页信息
     * @param userLevelLog 筛选信息
     * @return 用户等级记录列表
     */
    Page<UserLevelLog> getPage(Page<UserLevelLog> page, UserLevelLog userLevelLog);
    /**
     * 获取用户最高的等级(普通会员)
     * @param userId 用户id
     * @return 用户等级
     */
    Integer getMaxLevelByUserId(String userId);
    /**
     * 统计升级会员数
     * @param param 筛选数据
     * @return 升级会员数
     */
    CustomerMemberParam countMemberNum(CustomerReqParam param);
    /**
     * 获取用户最新的购买等级记录信息
     * @param userId 用户id
     * @return 等级记录信息
     */
    UserLevelLog getMaxCrtTimeByUserId(String userId);
    /**
     * 获取付费会员购买记录
     * @param page
     * @param userLevelLog
     * @return
     */
    IPage<UserLevelLog> pageBuyLevelLog(PageParam<UserLevelLog> page, UserLevelLog userLevelLog);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelRightsService.java
New file
@@ -0,0 +1,36 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.user.common.model.UserLevelRights;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelRightsService extends IService<UserLevelRights> {
    /**
     * 批量插入等级权益信息
     * @param rightsList 权益列表
     * @param id 等级id
     */
    void insertBatchRights(Long[] rightsList, Long id);
    /**
     * 批量删除等级权益信息
     * @param rightsList 权益列表
     * @param id 等级id
     */
    void delBatchRights(Long[] rightsList, Long id);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserLevelService.java
New file
@@ -0,0 +1,141 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.bo.PayInfoResultBO;
import com.yami.shop.bean.model.PayInfo;
import com.yami.shop.bean.model.UserExtension;
import com.yami.shop.bean.param.UserUpdateParam;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.user.common.dto.LevelDetailDto;
import com.yami.shop.user.common.dto.UserLevelDto;
import com.yami.shop.user.common.model.UserLevel;
import com.yami.shop.user.common.model.UserLevelLog;
import java.util.List;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserLevelService extends IService<UserLevel> {
    /**
     * 根据会员等级类型获取会员等级列表信息
     *
     * @param userLevelType 见 枚举UserLevelType
     * @return
     */
    List<UserLevelDto> listUserLevelsByUserLevelType(Integer userLevelType);
    /**
     * 根据会员等级类型移除会员等级列表缓存
     *
     * @param userLevelType 等级类型
     */
    void removeUserLevelsByUserLevelTypeCache(Integer userLevelType);
    /**
     * 购买会员回调
     * @param payInfoResultBO
     * @param payInfo
     * @return
     */
    ServerResponseEntity<String> noticeBuyVip(PayInfoResultBO payInfoResultBO, PayInfo payInfo);
    /**
     * 购买付费会员成功处理
     *
     * @param payNo 支付单号
     * @param userLevelLog
     */
    void paySuccess(String payNo, UserLevelLog userLevelLog, PayInfoResultBO payInfoResultBO);
    /**
     * 增加用户成长值和积分
     *
     * @param growthPrice 增加的成长值
     * @param score    增加的积分
     * @param userId    用户id
     * @param bizId    bizId
     * @param userExtension    用户扩展信息
     * @param type    1:等级 2:余额充值
     */
    void addGrowthAndScore(double growthPrice, Long score, String userId, String bizId, UserExtension userExtension, Integer type);
    /**
     * 等级提升
     * @param userLevels 多个等级,奖励发放时
     * @param userLevelLog 等级日志,在购买付费会员时存在
     * @param user 用户详细信息
     * @param historyLevel 等级提升后的等级
     * @param beforeLevel 等级提升前的等级
     */
    void levelUp(List<UserLevel> userLevels, UserLevelLog userLevelLog, UserExtension user, Integer historyLevel, Integer beforeLevel);
    /**
     * 更新等级模板信息
     * @param userLevel 等级信息
     */
    void updateUserLevelList(UserLevel userLevel);
    /**
     * 删除等级
     * @param userLevel 等级信息
     * @return 是否删除
     */
    Boolean deleteUserLevel(UserLevel userLevel);
    /**
     * 根据等级模板,更新用户的等级信息
     * @param userLevel 等级信息
     * @return 是否成功更新
     */
    Boolean updateUserLevel(UserLevel userLevel);
    /**
     * 获取等级信息
     * @param id 等级id
     * @return 等级信息
     */
    UserLevel getUserLevelById(Long id);
    /**
     * 获取用户所在等级的名称
     * @param userExtension 用户扩展信息
     * @return 等级名称
     */
    String getUserLevelName(UserExtension userExtension);
    /**
     * 获取等级列表,等级包含等级关联的权限列表信息
     * @param levelType 等级类型
     * @return 等级列表
     */
    List<LevelDetailDto> selectLevelAndRights(Integer levelType);
    /**
     * 批量修改用户成长值
     * @param param
     * @return
     */
    Boolean batchUpdateGrowth(UserUpdateParam param);
    /**
     * 批量修改用户积分
     * @param param
     * @return
     */
    Boolean batchUpdateScore(UserUpdateParam param);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserMemberService.java
New file
@@ -0,0 +1,38 @@
package com.yami.shop.user.common.service;
import com.yami.shop.bean.param.CustomerManagerParam;
import com.yami.shop.bean.param.UserExcelParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author: zsm
 * @date: 2023/1/15 9:05
 */
public interface UserMemberService {
    /**
     * 客户列表 - excel导出
     * @param customerParam
     * @param response
     */
    void exportCustomer(CustomerManagerParam customerParam, HttpServletResponse response);
    /**
     * 下载客户导入模板
     * @param  templateType
     * @param response
     */
    void downloadTemplate(Integer templateType, HttpServletResponse response);
    /**
     * 导入客户
     * @param shopId
     * @param excelFile
     * @return
     * @throws IOException
     */
    UserExcelParam importCustomer(Long shopId, MultipartFile excelFile) throws IOException;
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserRightsService.java
New file
@@ -0,0 +1,47 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.user.common.model.UserRights;
import java.util.List;
/**
 * 会员等级
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserRightsService extends IService<UserRights> {
    /**
     * 更新权益状态信息
     * @param rightsId 权益id
     * @param status 状态
     * @return 是否成功更新
     */
    Boolean setStatua(Long rightsId, Integer status);
    /**
     * 根据等级id,获取关联的权益列表
     * @param id 等级id
     * @param levelType 等级类型
     * @return 权益列表
     */
    List<Long> getUserRightsIdListByLevelId(Long id,Integer levelType);
    /**
     * 删除权益
     * @param rightsId 权益id
     * @return 是否成功删除
     */
    Boolean removeRights(Long rightsId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserScoreDetailService.java
New file
@@ -0,0 +1,101 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.user.common.model.UserScoreDetail;
import java.util.Date;
import java.util.List;
/**
 *
 *
 * @author lhd
 * @date 2020-05-25 15:31:02
 */
public interface UserScoreDetailService extends IService<UserScoreDetail> {
    /**
     * 修改用户过期积分
     * @param dateTime 过期时间
     */
    void updateExpireScoreDetail(DateTime dateTime);
//
//    /**
//     * 进行回退用户积分,并添加日志
//     * @param orderNumber 订单编号
//     * @param userId 用户id
//     */
//    void updateLogAndDetail(String orderNumber, String userId);
    /**
     * 保存用户积分明细(该方法需要在userExtension更新之前调用)
     * @param addDetail
     */
    void saveUserScoreDetail(UserScoreDetail addDetail);
    /**
     * 批量保存用户积分明细(该方法需要在userExtension更新之前调用)
     * @param userScoreDetails
     * @param userId
     */
    void saveBatchUserScoreDetail(List<UserScoreDetail> userScoreDetails, String userId);
    /**
     * 查询已经过期但还没标记的积分
     * @param userId 用户id
     * @param expireTime 过期时间
     * @param status 状态
     * @return 用户积分记录列表
     */
    List<UserScoreDetail> listByUserIdAndExpireTimeAndStatus(String userId, Date expireTime, Integer status);
    /**
     * 查询用户积分详细表数据
     * @param userId 用户id
     * @param status 状态
     * @return 用户积分详细表数据
     */
    List<UserScoreDetail> listByCreateTime(String userId, Integer status);
    /**
     * 查询用户积分记录列表
     * @param userId 用户id
     * @param status 状态
     * @param current 开始搜索的索引
     * @param size 分页的大小
     * @return
     */
    List<UserScoreDetail> listByCreateTimeAndPage(String userId, Integer status, Integer current, Integer size);
    /**
     * 获取用户年底将要过期的积分总数
     * @param userId 用户Id
     * @return 年底过期积分总数
     */
    Long getExpiringScoreByUserId(String userId);
    /**
     * 获取可用积分
     * @param userId
     * @return
     */
    Long getUsableScoreByUserId(String userId);
    /**
     * 根据id加积分
     * @param userId
     * @param amount
     */
    Boolean updateScore(String userId, Long amount);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserScoreLockService.java
New file
@@ -0,0 +1,37 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.dto.UserScoreLockDTO;
import com.yami.shop.bean.model.Order;
import com.yami.shop.user.common.model.UserScoreLock;
import java.util.List;
/**
 * 积分锁定信息
 *
 * @author lhd
 * @date 2022-05-06 17:27:53
 */
public interface UserScoreLockService extends IService<UserScoreLock> {
    /**
     * 按照订单号锁定积分
     * @param userScoreLocks 订单号和积分的集合
     */
    void lock(List<UserScoreLockDTO> userScoreLocks, String userId);
    /**
     * 按照订单号解锁积分
     * @param order 订单信息
     */
    void unlock(Order order);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserScoreLogService.java
New file
@@ -0,0 +1,55 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.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.user.common.model.UserScoreLog;
/**
 * 用户积分记录
 *
 * @author LGH
 * @date 2020-02-26 16:03:14
 */
public interface UserScoreLogService extends IService<UserScoreLog> {
    /**
     * 获取签到的天数
     * @param userId 用户id
     * @return 签到的天数
     */
    Integer getConsecutiveDays(String userId);
    /**
     * 分页获取用户积分记录
     * @param page 分页信息
     * @param userScoreLog 筛选信息
     * @return 用户积分记录
     */
    Page<UserScoreLog> getPage(PageParam<UserScoreLog> page, UserScoreLog userScoreLog);
    /**
     * 获取某个用户的积分明细
     * @param page 分页信息
     * @param userId 用户id
     * @return 指定用户id的积分明细
     */
    IPage<UserScoreLog> getPageByUserId(PageParam<UserScoreLog> page, String userId);
    /**
     * 缴纳幸运币后发放的积分
     * @param userId
     * @param paymentLuckyCoinAmount
     */
    void add(String userId, Long paymentLuckyCoinAmount);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserTagService.java
New file
@@ -0,0 +1,104 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
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.User;
import com.yami.shop.bean.param.UserUpdateParam;
import com.yami.shop.user.common.dto.UserTagDto;
import com.yami.shop.user.common.model.UserTag;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
 * 客户标签
 *
 * @author LGH
 * @date 2020-09-09 11:31:16
 */
public interface UserTagService extends IService<UserTag> {
    /**
     * 添加用户标签信息
     * @param userTagDto 标签信息
     * @return 结果
     */
    boolean addUserTag(UserTagDto userTagDto);
    /**
     * 修改用户标签信息
     * @param userTagDto 标签信息
     * @return 结果
     */
    boolean updateUserTag(UserTagDto userTagDto);
    /**
     * 删除用户标签信息
     * @param userTagId 标签id
     * @return 结果
     */
    boolean removeUserTag(Long userTagId);
    /**
     * 填充自定义可选条件
     * @param userTagDto  标签信息
     * @param userTag 客户标签
     * @param updateWrapper 更新实例
     */
    void fillInCustomOptionalCondition(UserTagDto userTagDto, UserTag userTag, UpdateWrapper<UserTag> updateWrapper);
    /**
     * 刷新条件标签统计人数
     * @param userTagId 用户标签id
     * @return 条件标签统计人数
     */
    UserTag refreshConditionTag(Long userTagId);
    /**
     * 根据"最近几天"求出具体日期
     * @param timeType 时间类型条件
     * @param localDateTime 时间
     * @return 具体日期
     */
    Date addDateTimeCondition(Integer timeType, LocalDateTime localDateTime);
    /**
     * 求两个List<User>之间的交集
     * @param users1 用户列表1
     * @param users2 用户列表2
     * @return list的交集
     */
    List<User> userFilter(List<User> users1, List<User> users2);
    /**
     * 发送标签消息
     * @param templateId 模板id
     */
    void sendTagMsg(Long templateId);
    /**
     * 批量修改用户标签
     * @param param 用户标签
     * @return 结果
     */
    Boolean batchUpdateUserTag(UserUpdateParam param);
    /**
     * 根据参数查询标签列表
     * @param page 分页参数
     * @param tagType 标签类型
     * @param tagName 标签名称
     * @return 标签列表
     */
    IPage<UserTag> pageUserTagByParam(Page page,Integer tagType,String tagName);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/UserTagUserService.java
New file
@@ -0,0 +1,58 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yami.shop.bean.param.UserTagParam;
import com.yami.shop.user.common.model.UserTagUser;
import java.util.List;
/**
 * 用户和标签关联表
 *
 * @author LGH
 * @date 2020-09-10 08:44:22
 */
public interface UserTagUserService extends IService<UserTagUser> {
    /**
     * 获取标签关联信息根据用户id和标签id
     * @param userId 用户id
     * @param tagId 标签id
     * @return 标签关联信息
     */
    UserTagUser getByUserIdAndTagId(String userId, Long tagId);
    /**
     * 获取用户的标签数量
     * @param userId 用户id
     * @param tagId 标签id
     * @return 结果
     */
    Integer countByUserIdAndTagId(String userId, Long tagId);
    /**
     * 获取用户的标签列表
     * @param userId 用户id
     * @return 标签列表
     */
    List<UserTagParam> getUserTagsUserByUserId(String userId);
    /**
     * 移除标签通过用户id和标签关联id
     * @param userId 用户id
     * @param userTagId 用户标签关联id
     * @return 结果
     */
    Boolean removeByUserIdAndTagId(String userId, Long userTagId);
}
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/ScoreOrderServiceImpl.java
New file
@@ -0,0 +1,361 @@
/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许,不可做商业用途!
 *
 * 版权所有,侵权必究!
 */
package com.yami.shop.user.common.service.impl;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.app.dto.ProductItemDto;
import com.yami.shop.bean.enums.*;
import com.yami.shop.bean.event.EsProductUpdateEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.dao.*;
import com.yami.shop.service.*;
import com.yami.shop.user.common.dto.ScoreOrderMergerDto;
import com.yami.shop.user.common.model.UserScoreDetail;
import com.yami.shop.user.common.model.UserScoreLog;
import com.yami.shop.user.common.service.ScoreOrderService;
import com.yami.shop.user.common.service.UserScoreDetailService;
import com.yami.shop.user.common.service.UserScoreLogService;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
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.*;
/**
 * @author LHD
 * @date 2019-12-12 13:55:57
 */
@Service
@AllArgsConstructor
public class ScoreOrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ScoreOrderService {
    private final OrderItemService orderItemService;
    private final UserScoreDetailService userScoreDetailService;
    private final UserScoreLogService userScoreLogService;
    private final UserExtensionService userExtensionService;
    private final OrderMapper orderMapper;
    private final OrderLangMapper orderLangMapper;
    private final SkuStockMapper skuStockMapper;
    private final MapperFacade mapperFacade;
    private final SkuService skuService;
    private final ProductService productService;
    private final ProdExtensionMapper prodExtensionMapper;
    private final UserAddrOrderService userAddrOrderService;
    private final Snowflake snowflake;
    private final OrderSettlementMapper orderSettlementMapper;
    private final ApplicationEventPublisher eventPublisher;
    @Override
    @CachePut(cacheNames = "ConfirmScoreOrderCache", key = "#userId")
    public ScoreOrderMergerDto putConfirmScoreOrderCache(String userId, ScoreOrderMergerDto scoreOrderMergerDto) {
        return scoreOrderMergerDto;
    }
    @Override
    @Cacheable(cacheNames = "ConfirmScoreOrderCache", key = "#userId")
    public ScoreOrderMergerDto getConfirmScoreOrderCache(String userId) {
        return null;
    }
    @Override
    @CacheEvict(cacheNames = "ConfirmScoreOrderCache", key = "#userId")
    public void removeConfirmScoreOrderCache(String userId) {
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order submit(String userId, ScoreOrderMergerDto mergerOrder) {
        // 提交订单
        Order scoreOrder = handlerOrder(mergerOrder);
        // 插入订单
        orderMapper.insert(scoreOrder);
        // 保存订单语言表
        orderLangMapper.insertBatchOrderLang(Collections.singletonList(scoreOrder));
        // 减少用户积分
        updateUserScore(mergerOrder,scoreOrder);
        // 插入订单项,返回主键
        orderItemService.insertBatchOrderItem(scoreOrder.getOrderItems());
        // 更新es商品库存
        eventPublisher.publishEvent(new EsProductUpdateEvent(mergerOrder.getProductItemDto().getProdId(), null, EsOperationType.UPDATE));
        return scoreOrder;
    }
    private void updateUserScore(ScoreOrderMergerDto mergerOrder,Order order) {
        UserExtension userExtension = userExtensionService.getOne(new LambdaQueryWrapper<UserExtension>().eq(UserExtension::getUserId, order.getUserId()));
        //查询积分详细表数据
        List<UserScoreDetail> scoreDetailList = userScoreDetailService.list(new LambdaQueryWrapper<UserScoreDetail>()
                .eq(UserScoreDetail::getUserId, userExtension.getUserId()).eq(UserScoreDetail::getStatus,1).orderByAsc(UserScoreDetail::getCreateTime));
        if(CollectionUtils.isEmpty(scoreDetailList)){
            // 积分不足无法提交订单
            throw new YamiShopBindException("yami.user.score.no.enough");
        }
        long score = scoreDetailList.stream().mapToLong(UserScoreDetail::getUsableScore).sum();
        Long scorePrice = mergerOrder.getProductItemDto().getScorePrice();
        List<UserScoreDetail> updateScoreDetails = new ArrayList<>();
        if(userExtension.getScore() < scorePrice || score < scorePrice.longValue()){
            // 积分不足无法提交订单
            throw new YamiShopBindException("yami.user.score.no.enough");
        }
        UserScoreLog userScoreLog = new UserScoreLog();
        userScoreLog.setUserId(order.getUserId());
        userScoreLog.setBizId(order.getOrderNumber());
        userScoreLog.setScore(scorePrice);
        userScoreLog.setSource(ScoreLogType.SCORE_CASH.value());
        userScoreLog.setCreateTime(new Date());
        userScoreLog.setIoType(0);
        // 修改积分明细,如果当前明细不够扣除在进行下一条
        // 如果够添加一条积分明细记录
        for (UserScoreDetail scoreDetail : scoreDetailList) {
            if(scoreDetail.getUsableScore() <= scorePrice){
                scoreDetail.setStatus(0);
                scoreDetail.setBizId(order.getOrderNumber());
                updateScoreDetails.add(scoreDetail);
                scorePrice -= scoreDetail.getUsableScore();
            }else{
                UserScoreDetail addDetail = new UserScoreDetail();
                addDetail.setCreateTime(scoreDetail.getCreateTime());
                addDetail.setStatus(0);
                addDetail.setUserId(scoreDetail.getUserId());
                addDetail.setBizId(order.getOrderNumber());
                addDetail.setUsableScore(scorePrice);
                userScoreDetailService.save(addDetail);
                scoreDetail.setUsableScore(scoreDetail.getUsableScore() - scorePrice);
                updateScoreDetails.add(scoreDetail);
                break;
            }
            if(scorePrice <= 0){
                break;
            }
        }
        userScoreLogService.save(userScoreLog);
        userScoreDetailService.updateBatchById(updateScoreDetails);
        //保存用户积分
        userExtension.setScore(userExtension.getScore() - mergerOrder.getProductItemDto().getScorePrice());
        userExtensionService.updateById(userExtension);
    }
    /**
     * 处理订单
     * @param mergerOrder
     * @return
     */
    private Order handlerOrder(ScoreOrderMergerDto mergerOrder){
        Date now = new Date();
        String userId = mergerOrder.getUserId();
        // 订单商品参数
        ProductItemDto productItemDto = mergerOrder.getProductItemDto();
        // 把订单地址保存到数据库
        UserAddrOrder userAddrOrder = mapperFacade.map(mergerOrder.getUserAddr(), UserAddrOrder.class);
        if (userAddrOrder == null) {
            // 请填写收货地址
            throw new YamiShopBindException("yami.delivery.address");
        }
        userAddrOrder.setUserId(userId);
        userAddrOrder.setCreateTime(now);
        userAddrOrderService.save(userAddrOrder);
        if(Objects.isNull(productItemDto)) {
            // 订单已经失效
            throw new YamiShopBindException("yami.order.expired");
        }
        // 订单地址id
        Long addrOrderId = userAddrOrder.getAddrOrderId();
        //检查sku和prod的库存
        Sku sku = checkAndGetSku(productItemDto.getSkuId(), productItemDto);
        Product product = checkAndGetProd(productItemDto.getProdId(), productItemDto);
        // 使用雪花算法生成的订单号
        String orderNumber = String.valueOf(snowflake.nextId());
        mergerOrder.setOrderNumber(orderNumber);
        OrderItem orderItem = mapperFacade.map(productItemDto, OrderItem.class);
        // 插入订单相关信息
        Order order = addOrderData(userId, now, orderNumber, sku, product, orderItem, mergerOrder, productItemDto);
        order.setAddrOrderId(addrOrderId);
        order.setReceiverName(userAddrOrder.getReceiver());
        order.setReceiverMobile(userAddrOrder.getMobile());
        Sku updateSku = new Sku();
        updateSku.setSkuId(sku.getSkuId());
        updateSku.setStocks(orderItem.getProdCount());
        Product updateProd = new Product();
        updateProd.setProdId(sku.getProdId());
        updateProd.setTotalStocks(orderItem.getProdCount());
        // 更新sku库存
        if (skuStockMapper.updateStocks(updateSku) == 0) {
            skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId());
            productService.removeProdCacheByProdId(sku.getProdId());
            // 商品库存不足
            String prodMsg = I18nMessage.getMessage("yami.product");
            String msg = I18nMessage.getMessage("yami.insufficient.inventory");
            throw new YamiShopBindException(prodMsg+"[" + sku.getProdName() + "]"+msg);
        }
        // 更新商品库存
        if (prodExtensionMapper.updateProdStocks(updateProd.getProdId()) == 0) {
            productService.removeProdCacheByProdId(product.getProdId());
            // 商品库存不足
            String prodMsg = I18nMessage.getMessage("yami.product");
            String msg = I18nMessage.getMessage("yami.insufficient.inventory");
            throw new YamiShopBindException(prodMsg+"[" + product.getProdName() + "]"+msg);
        }
        return order;
    }
    /**
     * 插入订单信息
     * @param userId 用户id
     * @param now 当前时间
     * @param orderNumber 订单编号
     * @param sku 商品规格
     * @param product 商品信息
     * @param orderItem 订单项
     * @param mergerOrder 订单提交信息
     * @param productItemDto 商品信息
     * @return 订单信息
     */
    private Order addOrderData(String userId, Date now, String orderNumber, Sku sku, Product product, OrderItem orderItem, ScoreOrderMergerDto mergerOrder, ProductItemDto productItemDto) {
        Long shopId = mergerOrder.getShopId();
        List<OrderItem> orderItems = new ArrayList<>();
        // 保存中英文名称
        orderItem.setProdNameCn(productItemDto.getProdNameCn());
        orderItem.setProdName(productItemDto.getProdNameCn());
        orderItem.setProdNameEn(productItemDto.getProdNameEn());
        orderItem.setPic(StrUtil.isBlank(sku.getPic()) ? product.getPic() : sku.getPic());
        orderItem.setShopId(shopId);
        orderItem.setOrderNumber(orderNumber);
        orderItem.setUserId(userId);
        orderItem.setRecTime(now);
        orderItem.setShareReduce(mergerOrder.getFreeTransfee());
        orderItem.setUseScore(mergerOrder.getProductItemDto().getScorePrice());
        orderItem.setCommSts(0);
        orderItems.add(orderItem);
        // 订单信息
        Order order = new Order();
        order.setShopId(shopId);
        order.setOrderNumber(orderNumber);
        // 订单商品名称
        order.setProdName(orderItem.getProdName());
        // 保存中英文名称
        order.setProdNameCn(productItemDto.getProdNameCn());
        order.setProdNameEn(productItemDto.getProdNameEn());
        // 用户id
        order.setUserId(userId);
        // 商品总额
        order.setTotal(mergerOrder.getTotal());
        // 实际总额
        order.setActualTotal(mergerOrder.getActualTotal());
        order.setPlatformAmount(mergerOrder.getFreeTransfee());
        order.setStatus(OrderStatus.UNPAY.value());
        order.setUpdateTime(now);
        order.setCreateTime(now);
        order.setIsPayed(0);
        order.setDeleteStatus(0);
        order.setProductNums(mergerOrder.getTotalCount());
        order.setOrderType(OrderType.SCORE.value());
        order.setDvyType(DvyType.DELIVERY.value());
        order.setReduceAmount(mergerOrder.getFreeTransfee());
        order.setFreightAmount(mergerOrder.getTotalTransfee() - mergerOrder.getFreeTransfee());
        order.setRemarks(mergerOrder.getRemarks());
        order.setPlatformFreeFreightAmount(mergerOrder.getFreeTransfee());
        order.setOrderItems(orderItems);
        //插入订单结算表
        OrderSettlement orderSettlement = new OrderSettlement();
        //orderSettlement.setUserId(userId);
        orderSettlement.setCreateTime(now);
        //orderSettlement.setIsClearing(0);
        orderSettlement.setOrderNumber(orderNumber);
        orderSettlement.setPayAmount(order.getActualTotal());
        orderSettlement.setPayStatus(0);
        orderSettlement.setVersion(0);
        //如果用使用积分,结算表将积分价格插入
        if(mergerOrder.getIsScorePay() != null && mergerOrder.getIsScorePay() == 1 && mergerOrder.getProductItemDto() != null){
            orderSettlement.setPayScore(mergerOrder.getProductItemDto().getScorePrice());
        }
        orderSettlementMapper.insert(orderSettlement);
        return order;
    }
    @SuppressWarnings({"Duplicates"})
    private Sku checkAndGetSku(Long skuId, ProductItemDto shopCartItem) {
        // 获取sku信息
        Sku sku = skuService.getSkuBySkuId(skuId, I18nMessage.getDbLang());
        // 当sku被删除时,不可以提交订单
        if (sku == null || sku.getIsDelete() == 1) {
            // 商品已售空或已下架
            throw new YamiShopBindException("yami.product.sold.out");
        }
        if (sku.getStatus() != 1) {
            String message = I18nMessage.getMessage("yami.product");
            String takeOff = I18nMessage.getMessage("yami.shopCart.take.off");
            // 商品已下架
            throw new YamiShopBindException(message+"[" + sku.getProdName() + "]"+takeOff);
        }
        // -1为无限库存
        if (sku.getStocks() != -1 && shopCartItem.getProdCount() > sku.getStocks()) {
            // 商品库存不足
            String prodMsg = I18nMessage.getMessage("yami.product");
            String msg = I18nMessage.getMessage("yami.insufficient.inventory");
            throw new YamiShopBindException(prodMsg+"[" + sku.getProdName() + "]"+msg);
        }
        if (sku.getStocks() != -1) {
            // 这里的库存是改变的库存
            sku.setStocks(shopCartItem.getProdCount());
        }
        return sku;
    }
    @SuppressWarnings({"Duplicates"})
    private Product checkAndGetProd(Long prodId, ProductItemDto productItemDto) {
        Product product = productService.getProductByProdId(prodId, I18nMessage.getDbLang());
        if (product == null) {
            // 商品已售空或已下架
            throw new YamiShopBindException("yami.product.sold.out");
        }
        if (product.getStatus() != 1) {
            String message = I18nMessage.getMessage("yami.product");
            String takeOff = I18nMessage.getMessage("yami.shopCart.take.off");
            // 商品已下架
            throw new YamiShopBindException(message+"[" + product.getProdName() + "]"+takeOff);
        }
        Integer totalStocks = product.getTotalStocks();
        // 商品需要改变的库存
        if (totalStocks != -1) {
            product.setTotalStocks(productItemDto.getProdCount());
        }
        // -1为无限库存
        if (totalStocks != -1 && product.getTotalStocks() > totalStocks) {
            // 商品库存不足
            String prodMsg = I18nMessage.getMessage("yami.product");
            String msg = I18nMessage.getMessage("yami.insufficient.inventory");
            throw new YamiShopBindException(prodMsg+"[" + product.getProdName() + "]"+msg);
        }
        return product;
    }
}
Diff truncated after the above file
yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserBalanceCouponServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserBalanceLogServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserBalanceServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserGrowthLogServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelCategoryServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelCouponServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelLogServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelRightsServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserLevelServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserMenberServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserRightsServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserScoreDetailServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserScoreLockServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserScoreLogServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserTagServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/service/impl/UserTagUserServiceImpl.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/task/ListCustomerExportDataTask.java yami-shop-user/yami-shop-user-common/src/main/java/com/yami/shop/user/common/util/CategoryScale.java yami-shop-user/yami-shop-user-common/src/main/resources/mapper/ScoreDetailMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserBalanceCouponMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserBalanceLogMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserBalanceMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserGrowthLogMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelCategoryMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelCouponMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelLogMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserLevelRightsMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserRightsMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserScoreLockMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserScoreLogMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserTagMapper.xml yami-shop-user/yami-shop-user-common/src/main/resources/mapper/UserTagUserMapper.xml yami-shop-user/yami-shop-user-multishop/pom.xml yami-shop-user/yami-shop-user-multishop/src/main/java/com/yami/shop/user/multishop/controller/UserMemberController.java yami-shop-user/yami-shop-user-multishop/src/main/java/com/yami/shop/user/multishop/task/ListCustomerExportDataTask.java yami-shop-user/yami-shop-user-platform/pom.xml yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/config/SwaggerConfiguration.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/GrowthConfigController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreConfigController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreDeliveryController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreExpireConfigController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreOrderController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/ScoreOtherConfigController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserBalanceController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserExtensionController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserGrowthLogController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserLevelCategoryController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserLevelController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserLevelLogController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserRightsController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserScoreLogController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/controller/UserTagController.java yami-shop-user/yami-shop-user-platform/src/main/java/com/yami/shop/user/platform/task/ScoreTask.java