From df5e2b7b438b4cfe3072b6c2d71df0d1549f5735 Mon Sep 17 00:00:00 2001 From: zyx <1029606625@qq.com> Date: Wed, 14 Jun 2023 19:56:33 +0800 Subject: [PATCH] =?UTF-8?q?6/14=20=E5=AE=8C=E6=88=90=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E9=A1=B5=E9=9D=A2=E6=95=B4=E5=90=88=E5=8F=8A=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 25 + LICENSE | 191 ++ README.md | 128 + docker-compose.yml | 14 + mt_db.sql | 1080 +++++++ pom.xml | 212 ++ renren-admin/Dockerfile | 7 + renren-admin/db/dm8.sql | 674 +++++ renren-admin/db/mysql.sql | 504 ++++ renren-admin/db/oracle.sql | 684 +++++ renren-admin/db/postgresql.sql | 699 +++++ renren-admin/db/sqlserver.sql | 674 +++++ renren-admin/pom.xml | 156 + .../main/java/io/renren/AdminApplication.java | 37 + .../renren/common/annotation/DataFilter.java | 37 + .../common/annotation/LogOperation.java | 24 + .../common/aspect/DataFilterAspect.java | 107 + .../common/aspect/LogOperationAspect.java | 110 + .../common/config/MybatisPlusConfig.java | 43 + .../renren/common/config/SwaggerConfig.java | 71 + .../common/exception/RenExceptionHandler.java | 94 + .../handler/FieldMetaObjectHandler.java | 79 + .../interceptor/DataFilterInterceptor.java | 89 + .../renren/common/interceptor/DataScope.java | 36 + .../io/renren/common/utils/ExcelUtils.java | 77 + .../common/validator/group/AliyunGroup.java | 17 + .../common/validator/group/QcloudGroup.java | 17 + .../common/validator/group/QiniuGroup.java | 17 + .../modules/front/bean/AddressBook.java | 121 + .../renren/modules/front/bean/Category.java | 66 + .../io/renren/modules/front/bean/Dish.java | 104 + .../renren/modules/front/bean/DishFlavor.java | 79 + .../modules/front/bean/OrderDetail.java | 69 + .../io/renren/modules/front/bean/Orders.java | 83 + .../io/renren/modules/front/bean/Setmeal.java | 91 + .../modules/front/bean/SetmealDish.java | 86 + .../modules/front/bean/ShoppingCart.java | 92 + .../io/renren/modules/front/bean/User.java | 91 + .../modules/front/common/CustomException.java | 15 + .../front/common/GlobalExceptionHandler.java | 32 + .../front/common/JacksonObjectMapper.java | 53 + .../modules/front/config/AlipayConfig.java | 28 + .../controller/AddressBookController.java | 79 + .../front/controller/AlipayController.java | 63 + .../front/controller/CategoryController.java | 68 + .../front/controller/DishController.java | 186 ++ .../controller/DishFlavorController.java | 24 + .../controller/OrderDetailController.java | 24 + .../front/controller/OrdersController.java | 88 + .../front/controller/SetmealController.java | 147 + .../controller/SetmealDishController.java | 43 + .../controller/ShoppingCartController.java | 59 + .../front/controller/UserController.java | 114 + .../modules/front/dao/AddressBookMapper.java | 15 + .../modules/front/dao/CategoryMapper.java | 15 + .../modules/front/dao/DishFlavorMapper.java | 15 + .../renren/modules/front/dao/DishMapper.java | 15 + .../modules/front/dao/OrderDetailMapper.java | 15 + .../modules/front/dao/OrdersMapper.java | 15 + .../modules/front/dao/SetmealDishMapper.java | 15 + .../modules/front/dao/SetmealMapper.java | 15 + .../modules/front/dao/ShoppingCartMapper.java | 15 + .../renren/modules/front/dao/UserMapper.java | 15 + .../io/renren/modules/front/dto/DishDTO.java | 24 + .../renren/modules/front/dto/OrdersDTO.java | 19 + .../renren/modules/front/dto/SetmealDTO.java | 22 + .../modules/front/dto/SetmealDishDTO.java | 17 + .../front/interceptor/LoginFilter.java | 82 + .../front/service/AddressBookService.java | 14 + .../front/service/CategoryService.java | 14 + .../front/service/DishFlavorService.java | 13 + .../modules/front/service/DishService.java | 17 + .../front/service/OrderDetailService.java | 13 + .../modules/front/service/OrdersService.java | 19 + .../front/service/SetmealDishService.java | 13 + .../modules/front/service/SetmealService.java | 16 + .../front/service/ShoppingCartService.java | 16 + .../modules/front/service/UserService.java | 13 + .../service/impl/AddressBookServiceImpl.java | 32 + .../service/impl/CategoryServiceImpl.java | 51 + .../service/impl/DishFlavorServiceImpl.java | 19 + .../front/service/impl/DishServiceImpl.java | 58 + .../service/impl/OrderDetailServiceImpl.java | 17 + .../front/service/impl/OrdersServiceImpl.java | 115 + .../service/impl/SetmealDishServiceImpl.java | 17 + .../service/impl/SetmealServiceImpl.java | 55 + .../service/impl/ShoppingCartServiceImpl.java | 71 + .../front/service/impl/UserServiceImpl.java | 17 + .../modules/front/utils/BaseContext.java | 24 + .../java/io/renren/modules/front/utils/R.java | 35 + .../modules/front/utils/SendEmailUtils.java | 53 + .../front/utils/ValidateCodeUtils.java | 43 + .../modules/job/config/ScheduleConfig.java | 66 + .../job/controller/ScheduleJobController.java | 133 + .../controller/ScheduleJobLogController.java | 63 + .../modules/job/dao/ScheduleJobDao.java | 29 + .../modules/job/dao/ScheduleJobLogDao.java | 23 + .../modules/job/dto/ScheduleJobDTO.java | 64 + .../modules/job/dto/ScheduleJobLogDTO.java | 53 + .../modules/job/entity/ScheduleJobEntity.java | 61 + .../job/entity/ScheduleJobLogEntity.java | 62 + .../job/init/JobCommandLineRunner.java | 47 + .../job/service/ScheduleJobLogService.java | 28 + .../job/service/ScheduleJobService.java | 63 + .../impl/ScheduleJobLogServiceImpl.java | 54 + .../service/impl/ScheduleJobServiceImpl.java | 130 + .../io/renren/modules/job/task/ITask.java | 25 + .../io/renren/modules/job/task/TestTask.java | 30 + .../renren/modules/job/utils/ScheduleJob.java | 79 + .../modules/job/utils/ScheduleUtils.java | 161 + .../log/controller/SysLogErrorController.java | 74 + .../log/controller/SysLogLoginController.java | 80 + .../controller/SysLogOperationController.java | 75 + .../modules/log/dao/SysLogErrorDao.java | 24 + .../modules/log/dao/SysLogLoginDao.java | 24 + .../modules/log/dao/SysLogOperationDao.java | 24 + .../modules/log/dto/SysLogErrorDTO.java | 46 + .../modules/log/dto/SysLogLoginDTO.java | 50 + .../modules/log/dto/SysLogOperationDTO.java | 62 + .../modules/log/entity/SysLogErrorEntity.java | 53 + .../modules/log/entity/SysLogLoginEntity.java | 49 + .../log/entity/SysLogOperationEntity.java | 64 + .../modules/log/enums/LoginOperationEnum.java | 36 + .../modules/log/enums/LoginStatusEnum.java | 40 + .../log/enums/OperationStatusEnum.java | 36 + .../modules/log/excel/SysLogErrorExcel.java | 37 + .../modules/log/excel/SysLogLoginExcel.java | 37 + .../log/excel/SysLogOperationExcel.java | 45 + .../log/service/SysLogErrorService.java | 34 + .../log/service/SysLogLoginService.java | 32 + .../log/service/SysLogOperationService.java | 32 + .../service/impl/SysLogErrorServiceImpl.java | 64 + .../service/impl/SysLogLoginServiceImpl.java | 71 + .../impl/SysLogOperationServiceImpl.java | 69 + .../cloud/AbstractCloudStorageService.java | 78 + .../oss/cloud/AliyunCloudStorageService.java | 57 + .../modules/oss/cloud/CloudStorageConfig.java | 110 + .../renren/modules/oss/cloud/OSSFactory.java | 41 + .../oss/cloud/QcloudCloudStorageService.java | 86 + .../oss/cloud/QiniuCloudStorageService.java | 79 + .../oss/controller/SysOssController.java | 132 + .../io/renren/modules/oss/dao/SysOssDao.java | 23 + .../modules/oss/entity/SysOssEntity.java | 32 + .../modules/oss/service/SysOssService.java | 25 + .../oss/service/impl/SysOssServiceImpl.java | 35 + .../modules/security/config/FilterConfig.java | 49 + .../modules/security/config/ShiroConfig.java | 104 + .../modules/security/config/WebMvcConfig.java | 80 + .../security/controller/LoginController.java | 155 + .../modules/security/dao/SysUserTokenDao.java | 29 + .../renren/modules/security/dto/LoginDTO.java | 44 + .../security/entity/SysUserTokenEntity.java | 54 + .../modules/security/oauth2/Oauth2Filter.java | 111 + .../modules/security/oauth2/Oauth2Realm.java | 92 + .../modules/security/oauth2/Oauth2Token.java | 34 + .../security/oauth2/TokenGenerator.java | 52 + .../modules/security/password/BCrypt.java | 662 ++++ .../password/BCryptPasswordEncoder.java | 82 + .../security/password/PasswordEncoder.java | 30 + .../security/password/PasswordUtils.java | 58 + .../security/service/CaptchaService.java | 33 + .../security/service/ShiroService.java | 43 + .../security/service/SysUserTokenService.java | 34 + .../service/impl/CaptchaServiceImpl.java | 100 + .../service/impl/ShiroServiceImpl.java | 76 + .../service/impl/SysUserTokenServiceImpl.java | 86 + .../modules/security/user/SecurityUser.java | 59 + .../modules/security/user/UserDetail.java | 41 + .../sys/controller/IndexController.java | 20 + .../sys/controller/SysDeptController.java | 98 + .../sys/controller/SysDictDataController.java | 110 + .../sys/controller/SysDictTypeController.java | 120 + .../sys/controller/SysMenuController.java | 138 + .../sys/controller/SysParamsController.java | 126 + .../sys/controller/SysRoleController.java | 133 + .../sys/controller/SysUserController.java | 165 + .../io/renren/modules/sys/dao/SysDeptDao.java | 41 + .../modules/sys/dao/SysDictDataDao.java | 30 + .../modules/sys/dao/SysDictTypeDao.java | 31 + .../io/renren/modules/sys/dao/SysMenuDao.java | 60 + .../renren/modules/sys/dao/SysParamsDao.java | 46 + .../io/renren/modules/sys/dao/SysRoleDao.java | 24 + .../modules/sys/dao/SysRoleDataScopeDao.java | 41 + .../modules/sys/dao/SysRoleMenuDao.java | 41 + .../modules/sys/dao/SysRoleUserDao.java | 45 + .../io/renren/modules/sys/dao/SysUserDao.java | 44 + .../renren/modules/sys/dto/PasswordDTO.java | 37 + .../io/renren/modules/sys/dto/SysDeptDTO.java | 111 + .../modules/sys/dto/SysDictDataDTO.java | 66 + .../modules/sys/dto/SysDictTypeDTO.java | 63 + .../io/renren/modules/sys/dto/SysMenuDTO.java | 157 + .../renren/modules/sys/dto/SysParamsDTO.java | 60 + .../io/renren/modules/sys/dto/SysRoleDTO.java | 59 + .../io/renren/modules/sys/dto/SysUserDTO.java | 93 + .../io/renren/modules/sys/dto/SystemDTO.java | 48 + .../renren/modules/sys/entity/DictData.java | 25 + .../renren/modules/sys/entity/DictType.java | 28 + .../modules/sys/entity/SysDeptEntity.java | 63 + .../modules/sys/entity/SysDictDataEntity.java | 60 + .../modules/sys/entity/SysDictTypeEntity.java | 56 + .../modules/sys/entity/SysMenuEntity.java | 75 + .../modules/sys/entity/SysParamsEntity.java | 59 + .../sys/entity/SysRoleDataScopeEntity.java | 37 + .../modules/sys/entity/SysRoleEntity.java | 54 + .../modules/sys/entity/SysRoleMenuEntity.java | 36 + .../modules/sys/entity/SysRoleUserEntity.java | 37 + .../modules/sys/entity/SysUserEntity.java | 86 + .../modules/sys/enums/MenuTypeEnum.java | 36 + .../modules/sys/enums/SuperAdminEnum.java | 30 + .../modules/sys/enums/UserStatusEnum.java | 30 + .../modules/sys/excel/SysParamsExcel.java | 29 + .../modules/sys/excel/SysUserExcel.java | 43 + .../modules/sys/redis/SysParamsRedis.java | 45 + .../modules/sys/service/SysDeptService.java | 40 + .../sys/service/SysDictDataService.java | 35 + .../sys/service/SysDictTypeService.java | 42 + .../modules/sys/service/SysMenuService.java | 54 + .../modules/sys/service/SysParamsService.java | 60 + .../sys/service/SysRoleDataScopeService.java | 41 + .../sys/service/SysRoleMenuService.java | 47 + .../modules/sys/service/SysRoleService.java | 40 + .../sys/service/SysRoleUserService.java | 48 + .../modules/sys/service/SysUserService.java | 58 + .../sys/service/impl/SysDeptServiceImpl.java | 165 + .../service/impl/SysDictDataServiceImpl.java | 88 + .../service/impl/SysDictTypeServiceImpl.java | 106 + .../sys/service/impl/SysMenuServiceImpl.java | 109 + .../service/impl/SysParamsServiceImpl.java | 142 + .../impl/SysRoleDataScopeServiceImpl.java | 62 + .../service/impl/SysRoleMenuServiceImpl.java | 69 + .../sys/service/impl/SysRoleServiceImpl.java | 135 + .../service/impl/SysRoleUserServiceImpl.java | 65 + .../sys/service/impl/SysUserServiceImpl.java | 158 + .../controller/AddressBookController.java | 116 + .../controller/CategoryController.java | 120 + .../takeout/controller/DishController.java | 126 + .../controller/DishFlavorController.java | 116 + .../controller/OrderDetailController.java | 116 + .../takeout/controller/OrdersController.java | 116 + .../takeout/controller/SetmealController.java | 120 + .../controller/SetmealDishController.java | 116 + .../controller/ShoppingCartController.java | 116 + .../takeout/controller/UserController.java | 116 + .../modules/takeout/dao/AddressBookDao.java | 16 + .../modules/takeout/dao/CategoryDao.java | 16 + .../renren/modules/takeout/dao/DishDao.java | 16 + .../modules/takeout/dao/DishFlavorDao.java | 16 + .../modules/takeout/dao/OrderDetailDao.java | 16 + .../renren/modules/takeout/dao/OrdersDao.java | 16 + .../modules/takeout/dao/SetmealDao.java | 16 + .../modules/takeout/dao/SetmealDishDao.java | 16 + .../modules/takeout/dao/ShoppingCartDao.java | 16 + .../renren/modules/takeout/dao/UserDao.java | 16 + .../modules/takeout/dto/AddressBookDTO.java | 80 + .../modules/takeout/dto/CategoryDTO.java | 47 + .../renren/modules/takeout/dto/DishDTO.java | 65 + .../modules/takeout/dto/DishFlavorDTO.java | 50 + .../modules/takeout/dto/OrderDetailDTO.java | 49 + .../renren/modules/takeout/dto/OrdersDTO.java | 65 + .../modules/takeout/dto/SetmealDTO.java | 62 + .../modules/takeout/dto/SetmealDishDTO.java | 59 + .../modules/takeout/dto/ShoppingCartDTO.java | 62 + .../renren/modules/takeout/dto/UserDTO.java | 62 + .../takeout/entity/AddressBookEntity.java | 94 + .../takeout/entity/CategoryEntity.java | 50 + .../modules/takeout/entity/DishEntity.java | 75 + .../takeout/entity/DishFlavorEntity.java | 54 + .../takeout/entity/OrderDetailEntity.java | 54 + .../modules/takeout/entity/OrdersEntity.java | 75 + .../takeout/entity/SetmealDishEntity.java | 67 + .../modules/takeout/entity/SetmealEntity.java | 71 + .../takeout/entity/ShoppingCartEntity.java | 71 + .../modules/takeout/entity/UserEntity.java | 70 + .../takeout/excel/AddressBookExcel.java | 55 + .../modules/takeout/excel/CategoryExcel.java | 33 + .../modules/takeout/excel/DishExcel.java | 46 + .../takeout/excel/DishFlavorExcel.java | 35 + .../takeout/excel/OrderDetailExcel.java | 35 + .../modules/takeout/excel/OrdersExcel.java | 46 + .../takeout/excel/SetmealDishExcel.java | 42 + .../modules/takeout/excel/SetmealExcel.java | 44 + .../takeout/excel/ShoppingCartExcel.java | 44 + .../modules/takeout/excel/UserExcel.java | 43 + .../takeout/service/AddressBookService.java | 15 + .../takeout/service/CategoryService.java | 15 + .../takeout/service/DishFlavorService.java | 15 + .../modules/takeout/service/DishService.java | 15 + .../takeout/service/OrderDetailService.java | 15 + .../takeout/service/OrdersService.java | 15 + .../takeout/service/SetmealDishService.java | 15 + .../takeout/service/SetmealService.java | 15 + .../takeout/service/ShoppingCartService.java | 15 + .../modules/takeout/service/UserService.java | 15 + .../service/impl/AddressBookServiceImpl.java | 34 + .../service/impl/CategoryServiceImpl.java | 34 + .../service/impl/DishFlavorServiceImpl.java | 34 + .../takeout/service/impl/DishServiceImpl.java | 34 + .../service/impl/OrderDetailServiceImpl.java | 34 + .../service/impl/OrdersServiceImpl.java | 34 + .../service/impl/SetmealDishServiceImpl.java | 34 + .../service/impl/SetmealServiceImpl.java | 34 + .../service/impl/ShoppingCartServiceImpl.java | 34 + .../takeout/service/impl/UserServiceImpl.java | 34 + .../src/main/resources/application-dev.yml | 69 + .../src/main/resources/application-prod.yml | 34 + .../src/main/resources/application-test.yml | 34 + .../src/main/resources/application.yml | 83 + renren-admin/src/main/resources/banner.txt | 5 + .../src/main/resources/logback-spring.xml | 21 + .../resources/mapper/job/ScheduleJobDao.xml | 14 + .../mapper/job/ScheduleJobLogDao.xml | 7 + .../resources/mapper/log/SysLogErrorDao.xml | 6 + .../resources/mapper/log/SysLogLoginDao.xml | 6 + .../mapper/log/SysLogOperationDao.xml | 6 + .../main/resources/mapper/oss/SysOssDao.xml | 7 + .../main/resources/mapper/sys/SysDeptDao.xml | 32 + .../resources/mapper/sys/SysDictDataDao.xml | 10 + .../resources/mapper/sys/SysDictTypeDao.xml | 10 + .../main/resources/mapper/sys/SysMenuDao.xml | 46 + .../resources/mapper/sys/SysParamsDao.xml | 23 + .../main/resources/mapper/sys/SysRoleDao.xml | 7 + .../mapper/sys/SysRoleDataScopeDao.xml | 22 + .../resources/mapper/sys/SysRoleMenuDao.xml | 20 + .../resources/mapper/sys/SysRoleUserDao.xml | 24 + .../main/resources/mapper/sys/SysUserDao.xml | 50 + .../resources/mapper/sys/SysUserTokenDao.xml | 17 + renren-admin/src/main/resources/public/1.png | Bin 0 -> 299702 bytes renren-admin/src/main/resources/public/2.png | Bin 0 -> 306510 bytes .../src/main/resources/public/favicon.ico | Bin 0 -> 4286 bytes .../src/main/resources/public/wechat.jpg | Bin 0 -> 27504 bytes .../java/io/renren/DynamicDataSourceTest.java | 39 + .../src/test/java/io/renren/RedisTest.java | 35 + .../service/DynamicDataSourceTestService.java | 59 + renren-api/Dockerfile | 7 + renren-api/db/dm8.sql | 27 + renren-api/db/mysql.sql | 25 + renren-api/db/oracle.sql | 24 + renren-api/db/postgresql.sql | 24 + renren-api/db/sqlserver.sql | 24 + renren-api/pom.xml | 52 + .../main/java/io/renren/ApiApplication.java | 32 + .../main/java/io/renren/annotation/Login.java | 21 + .../java/io/renren/annotation/LoginUser.java | 25 + .../java/io/renren/config/FilterConfig.java | 35 + .../io/renren/config/MybatisPlusConfig.java | 42 + .../java/io/renren/config/SwaggerConfig.java | 66 + .../java/io/renren/config/WebMvcConfig.java | 86 + .../renren/controller/ApiLoginController.java | 61 + .../controller/ApiRegisterController.java | 54 + .../renren/controller/ApiTestController.java | 53 + .../src/main/java/io/renren/dao/TokenDao.java | 25 + .../src/main/java/io/renren/dao/UserDao.java | 25 + .../src/main/java/io/renren/dto/LoginDTO.java | 34 + .../main/java/io/renren/dto/RegisterDTO.java | 33 + .../java/io/renren/entity/TokenEntity.java | 47 + .../java/io/renren/entity/UserEntity.java | 52 + .../renren/exception/RenExceptionHandler.java | 55 + .../interceptor/AuthorizationInterceptor.java | 73 + ...oginUserHandlerMethodArgumentResolver.java | 53 + .../java/io/renren/service/TokenService.java | 36 + .../java/io/renren/service/UserService.java | 34 + .../renren/service/impl/TokenServiceImpl.java | 92 + .../renren/service/impl/UserServiceImpl.java | 63 + .../src/main/resources/application-dev.yml | 33 + .../src/main/resources/application-prod.yml | 33 + .../src/main/resources/application-test.yml | 33 + renren-api/src/main/resources/application.yml | 81 + renren-api/src/main/resources/banner.txt | 5 + .../src/main/resources/logback-spring.xml | 21 + .../src/main/resources/mapper/TokenDao.xml | 14 + .../src/main/resources/mapper/UserDao.xml | 13 + renren-common/pom.xml | 24 + .../io/renren/common/aspect/RedisAspect.java | 49 + .../io/renren/common/constant/Constant.java | 127 + .../renren/common/convert/DateConverter.java | 79 + .../java/io/renren/common/dao/BaseDao.java | 21 + .../io/renren/common/entity/BaseEntity.java | 41 + .../io/renren/common/exception/ErrorCode.java | 46 + .../common/exception/ExceptionUtils.java | 53 + .../renren/common/exception/RenException.java | 75 + .../java/io/renren/common/page/PageData.java | 43 + .../io/renren/common/redis/RedisConfig.java | 102 + .../io/renren/common/redis/RedisKeys.java | 64 + .../io/renren/common/redis/RedisUtils.java | 126 + .../io/renren/common/service/BaseService.java | 116 + .../io/renren/common/service/CrudService.java | 35 + .../common/service/impl/BaseServiceImpl.java | 219 ++ .../common/service/impl/CrudServiceImpl.java | 80 + .../io/renren/common/utils/ConvertUtils.java | 60 + .../io/renren/common/utils/DateUtils.java | 182 ++ .../renren/common/utils/HttpContextUtils.java | 63 + .../java/io/renren/common/utils/IpUtils.java | 58 + .../io/renren/common/utils/JsonUtils.java | 68 + .../io/renren/common/utils/MessageUtils.java | 33 + .../java/io/renren/common/utils/Result.java | 98 + .../common/utils/SpringContextUtils.java | 55 + .../java/io/renren/common/utils/TreeNode.java | 38 + .../io/renren/common/utils/TreeUtils.java | 80 + .../renren/common/validator/AssertUtils.java | 98 + .../common/validator/ValidatorUtils.java | 57 + .../common/validator/group/AddGroup.java | 19 + .../common/validator/group/DefaultGroup.java | 19 + .../renren/common/validator/group/Group.java | 22 + .../common/validator/group/UpdateGroup.java | 19 + .../java/io/renren/common/xss/SqlFilter.java | 50 + .../java/io/renren/common/xss/XssFilter.java | 37 + .../xss/XssHttpServletRequestWrapper.java | 154 + .../java/io/renren/common/xss/XssUtils.java | 78 + .../main/resources/i18n/messages.properties | 26 + .../main/resources/i18n/validation.properties | 67 + renren-dynamic-datasource/pom.xml | 16 + .../datasource/annotation/DataSource.java | 25 + .../datasource/aspect/DataSourceAspect.java | 71 + .../config/DynamicContextHolder.java | 57 + .../datasource/config/DynamicDataSource.java | 26 + .../config/DynamicDataSourceConfig.java | 64 + .../config/DynamicDataSourceFactory.java | 54 + .../properties/DataSourceProperties.java | 202 ++ .../DynamicDataSourceProperties.java | 33 + renren-generator/pom.xml | 135 + .../java/io/renren/GeneratorApplication.java | 25 + .../main/java/io/renren/config/DbConfig.java | 52 + .../controller/SysGeneratorController.java | 62 + .../main/java/io/renren/dao/GeneratorDao.java | 25 + .../java/io/renren/dao/MySQLGeneratorDao.java | 23 + .../io/renren/dao/OracleGeneratorDao.java | 21 + .../io/renren/dao/PostgreSQLGeneratorDao.java | 21 + .../io/renren/dao/SQLServerGeneratorDao.java | 21 + .../java/io/renren/entity/ColumnEntity.java | 75 + .../java/io/renren/entity/TableEntity.java | 69 + .../renren/service/SysGeneratorService.java | 66 + .../src/main/java/io/renren/utils/Assert.java | 77 + .../main/java/io/renren/utils/DateUtils.java | 36 + .../main/java/io/renren/utils/GenUtils.java | 254 ++ .../main/java/io/renren/utils/IdWorker.java | 67 + .../main/java/io/renren/utils/PageUtils.java | 87 + .../src/main/java/io/renren/utils/Query.java | 53 + .../src/main/java/io/renren/utils/R.java | 62 + .../java/io/renren/utils/RenException.java | 61 + .../io/renren/utils/RenExceptionHandler.java | 42 + .../main/java/io/renren/utils/Sequence.java | 203 ++ .../main/java/io/renren/utils/StringPool.java | 95 + .../java/io/renren/utils/SystemClock.java | 80 + .../src/main/resources/application.yml | 50 + .../src/main/resources/generator.properties | 68 + .../src/main/resources/logback-spring.xml | 11 + .../resources/mapper/MySQLGeneratorDao.xml | 23 + .../resources/mapper/OracleGeneratorDao.xml | 83 + .../mapper/PostgreSQLGeneratorDao.xml | 37 + .../mapper/SQLServerGeneratorDao.xml | 90 + .../resources/static/css/AdminLTE.min.css | 7 + .../resources/static/css/all-skins.min.css | 1 + .../resources/static/css/bootstrap.min.css | 6 + .../resources/static/css/font-awesome.min.css | 4 + .../src/main/resources/static/css/main.css | 54 + .../src/main/resources/static/favicon.ico | Bin 0 -> 4286 bytes .../resources/static/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes .../static/fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../static/fonts/fontawesome-webfont.svg | 2671 +++++++++++++++++ .../static/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../static/fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../static/fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 ++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../src/main/resources/static/js/common.js | 83 + .../src/main/resources/static/js/generator.js | 60 + .../src/main/resources/static/js/index.js | 52 + .../src/main/resources/static/libs/app.js | 763 +++++ .../src/main/resources/static/libs/app.min.js | 13 + .../resources/static/libs/bootstrap.min.js | 7 + .../resources/static/libs/fastclick.min.js | 1 + .../main/resources/static/libs/jquery.min.js | 4 + .../static/libs/jquery.slimscroll.min.js | 1 + .../src/main/resources/static/libs/router.js | 97 + .../src/main/resources/static/libs/vue.min.js | 8 + .../static/plugins/jqgrid/grid.locale-cn.js | 219 ++ .../plugins/jqgrid/jquery.jqGrid.min.js | 1531 ++++++++++ .../plugins/jqgrid/ui.jqgrid-bootstrap-ui.css | 31 + .../plugins/jqgrid/ui.jqgrid-bootstrap.css | 930 ++++++ .../static/plugins/jqgrid/ui.jqgrid.css | 354 +++ .../resources/static/plugins/layer/layer.js | 2 + .../static/plugins/layer/mobile/layer.js | 2 + .../plugins/layer/mobile/need/layer.css | 1 + .../plugins/layer/skin/default/icon-ext.png | Bin 0 -> 5911 bytes .../plugins/layer/skin/default/icon.png | Bin 0 -> 11493 bytes .../plugins/layer/skin/default/layer.css | 1 + .../plugins/layer/skin/default/loading-0.gif | Bin 0 -> 5793 bytes .../plugins/layer/skin/default/loading-1.gif | Bin 0 -> 701 bytes .../plugins/layer/skin/default/loading-2.gif | Bin 0 -> 1787 bytes .../plugins/layer/skin/moon/default.png | Bin 0 -> 7563 bytes .../static/plugins/layer/skin/moon/style.css | 1 + .../resources/template/Controller.java.vm | 116 + .../src/main/resources/template/DTO.java.vm | 31 + .../src/main/resources/template/Dao.java.vm | 16 + .../src/main/resources/template/Dao.xml.vm | 13 + .../main/resources/template/Entity.java.vm | 27 + .../src/main/resources/template/Excel.java.vm | 24 + .../main/resources/template/Service.java.vm | 15 + .../resources/template/ServiceImpl.java.vm | 34 + .../resources/template/add-or-update.vue.vm | 94 + .../src/main/resources/template/index.vue.vm | 72 + .../src/main/resources/template/mysql.vm | 7 + .../src/main/resources/template/oracle.vm | 7 + .../src/main/resources/template/postgresql.vm | 7 + .../src/main/resources/template/sqlserver.vm | 7 + .../src/main/resources/views/generator.html | 35 + .../src/main/resources/views/index.html | 115 + .../src/main/resources/views/main.html | 29 + 511 files changed, 37288 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 mt_db.sql create mode 100644 pom.xml create mode 100644 renren-admin/Dockerfile create mode 100644 renren-admin/db/dm8.sql create mode 100644 renren-admin/db/mysql.sql create mode 100644 renren-admin/db/oracle.sql create mode 100644 renren-admin/db/postgresql.sql create mode 100644 renren-admin/db/sqlserver.sql create mode 100644 renren-admin/pom.xml create mode 100644 renren-admin/src/main/java/io/renren/AdminApplication.java create mode 100644 renren-admin/src/main/java/io/renren/common/annotation/DataFilter.java create mode 100644 renren-admin/src/main/java/io/renren/common/annotation/LogOperation.java create mode 100644 renren-admin/src/main/java/io/renren/common/aspect/DataFilterAspect.java create mode 100644 renren-admin/src/main/java/io/renren/common/aspect/LogOperationAspect.java create mode 100644 renren-admin/src/main/java/io/renren/common/config/MybatisPlusConfig.java create mode 100644 renren-admin/src/main/java/io/renren/common/config/SwaggerConfig.java create mode 100644 renren-admin/src/main/java/io/renren/common/exception/RenExceptionHandler.java create mode 100644 renren-admin/src/main/java/io/renren/common/handler/FieldMetaObjectHandler.java create mode 100644 renren-admin/src/main/java/io/renren/common/interceptor/DataFilterInterceptor.java create mode 100644 renren-admin/src/main/java/io/renren/common/interceptor/DataScope.java create mode 100644 renren-admin/src/main/java/io/renren/common/utils/ExcelUtils.java create mode 100644 renren-admin/src/main/java/io/renren/common/validator/group/AliyunGroup.java create mode 100644 renren-admin/src/main/java/io/renren/common/validator/group/QcloudGroup.java create mode 100644 renren-admin/src/main/java/io/renren/common/validator/group/QiniuGroup.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/AddressBook.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/Category.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/Dish.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/DishFlavor.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/OrderDetail.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/Orders.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/Setmeal.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/SetmealDish.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/ShoppingCart.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/bean/User.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/common/CustomException.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/common/GlobalExceptionHandler.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/common/JacksonObjectMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/config/AlipayConfig.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/AddressBookController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/AlipayController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/CategoryController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/DishController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/DishFlavorController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/OrderDetailController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/OrdersController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/SetmealController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/SetmealDishController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/ShoppingCartController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/controller/UserController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/AddressBookMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/CategoryMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/DishFlavorMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/DishMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/OrderDetailMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/OrdersMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/SetmealDishMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/SetmealMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/ShoppingCartMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dao/UserMapper.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dto/DishDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dto/OrdersDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDishDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/interceptor/LoginFilter.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/AddressBookService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/CategoryService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/DishFlavorService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/DishService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/OrderDetailService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/OrdersService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/SetmealDishService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/SetmealService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/ShoppingCartService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/UserService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/AddressBookServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/CategoryServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/DishFlavorServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/DishServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/OrderDetailServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/OrdersServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealDishServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/ShoppingCartServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/service/impl/UserServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/utils/BaseContext.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/utils/R.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/utils/SendEmailUtils.java create mode 100644 renren-admin/src/main/java/io/renren/modules/front/utils/ValidateCodeUtils.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/config/ScheduleConfig.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobLogDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/init/JobCommandLineRunner.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/task/ITask.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/task/TestTask.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleJob.java create mode 100644 renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/controller/SysLogErrorController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/controller/SysLogLoginController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/controller/SysLogOperationController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/dao/SysLogErrorDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/dao/SysLogLoginDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/dao/SysLogOperationDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/dto/SysLogErrorDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/dto/SysLogLoginDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/dto/SysLogOperationDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/entity/SysLogErrorEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/entity/SysLogLoginEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/entity/SysLogOperationEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/enums/LoginOperationEnum.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/enums/LoginStatusEnum.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/enums/OperationStatusEnum.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/excel/SysLogErrorExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/excel/SysLogLoginExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/excel/SysLogOperationExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/service/SysLogErrorService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/service/SysLogLoginService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/service/SysLogOperationService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogErrorServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogLoginServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogOperationServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/cloud/AbstractCloudStorageService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/dao/SysOssDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/service/SysOssService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/config/FilterConfig.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/config/ShiroConfig.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/config/WebMvcConfig.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/controller/LoginController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/dao/SysUserTokenDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/dto/LoginDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/entity/SysUserTokenEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Filter.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Realm.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Token.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/oauth2/TokenGenerator.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/password/BCrypt.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/password/BCryptPasswordEncoder.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/password/PasswordEncoder.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/password/PasswordUtils.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/service/CaptchaService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/service/ShiroService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/service/SysUserTokenService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/service/impl/CaptchaServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/service/impl/ShiroServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/service/impl/SysUserTokenServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/user/SecurityUser.java create mode 100644 renren-admin/src/main/java/io/renren/modules/security/user/UserDetail.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/IndexController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/SysDeptController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictDataController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictTypeController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/SysMenuController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/SysParamsController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/SysRoleController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/controller/SysUserController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysDeptDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictDataDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictTypeDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysParamsDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDataScopeDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleUserDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dao/SysUserDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/PasswordDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SysDeptDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictDataDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictTypeDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SysMenuDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SysParamsDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SysRoleDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SysUserDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/dto/SystemDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/DictData.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/DictType.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysDeptEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictDataEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictTypeEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysParamsEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleDataScopeEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleUserEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/enums/MenuTypeEnum.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/enums/SuperAdminEnum.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/enums/UserStatusEnum.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/excel/SysParamsExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/excel/SysUserExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/redis/SysParamsRedis.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysDeptService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysDictDataService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysDictTypeService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysMenuService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysParamsService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleDataScopeService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleUserService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/SysUserService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDeptServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictDataServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictTypeServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysParamsServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleUserServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/AddressBookController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/CategoryController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/DishController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/DishFlavorController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/OrderDetailController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/OrdersController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealDishController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/ShoppingCartController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/controller/UserController.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/AddressBookDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/CategoryDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/DishDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/DishFlavorDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/OrderDetailDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/OrdersDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDishDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/ShoppingCartDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dao/UserDao.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/AddressBookDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/CategoryDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/DishDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/DishFlavorDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/OrderDetailDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/OrdersDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDishDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/ShoppingCartDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/dto/UserDTO.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/AddressBookEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/CategoryEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/DishEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/DishFlavorEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/OrderDetailEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/OrdersEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealDishEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/ShoppingCartEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/entity/UserEntity.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/AddressBookExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/CategoryExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/DishExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/DishFlavorExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/OrderDetailExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/OrdersExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealDishExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/ShoppingCartExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/excel/UserExcel.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/AddressBookService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/CategoryService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/DishFlavorService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/DishService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/OrderDetailService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/OrdersService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealDishService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/ShoppingCartService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/UserService.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/AddressBookServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/CategoryServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishFlavorServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrderDetailServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrdersServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealDishServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/ShoppingCartServiceImpl.java create mode 100644 renren-admin/src/main/java/io/renren/modules/takeout/service/impl/UserServiceImpl.java create mode 100644 renren-admin/src/main/resources/application-dev.yml create mode 100644 renren-admin/src/main/resources/application-prod.yml create mode 100644 renren-admin/src/main/resources/application-test.yml create mode 100644 renren-admin/src/main/resources/application.yml create mode 100644 renren-admin/src/main/resources/banner.txt create mode 100644 renren-admin/src/main/resources/logback-spring.xml create mode 100644 renren-admin/src/main/resources/mapper/job/ScheduleJobDao.xml create mode 100644 renren-admin/src/main/resources/mapper/job/ScheduleJobLogDao.xml create mode 100644 renren-admin/src/main/resources/mapper/log/SysLogErrorDao.xml create mode 100644 renren-admin/src/main/resources/mapper/log/SysLogLoginDao.xml create mode 100644 renren-admin/src/main/resources/mapper/log/SysLogOperationDao.xml create mode 100644 renren-admin/src/main/resources/mapper/oss/SysOssDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysDeptDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysDictDataDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysDictTypeDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysMenuDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysParamsDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysRoleDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysRoleDataScopeDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysRoleMenuDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysRoleUserDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysUserDao.xml create mode 100644 renren-admin/src/main/resources/mapper/sys/SysUserTokenDao.xml create mode 100644 renren-admin/src/main/resources/public/1.png create mode 100644 renren-admin/src/main/resources/public/2.png create mode 100644 renren-admin/src/main/resources/public/favicon.ico create mode 100644 renren-admin/src/main/resources/public/wechat.jpg create mode 100644 renren-admin/src/test/java/io/renren/DynamicDataSourceTest.java create mode 100644 renren-admin/src/test/java/io/renren/RedisTest.java create mode 100644 renren-admin/src/test/java/io/renren/service/DynamicDataSourceTestService.java create mode 100644 renren-api/Dockerfile create mode 100644 renren-api/db/dm8.sql create mode 100644 renren-api/db/mysql.sql create mode 100644 renren-api/db/oracle.sql create mode 100644 renren-api/db/postgresql.sql create mode 100644 renren-api/db/sqlserver.sql create mode 100644 renren-api/pom.xml create mode 100644 renren-api/src/main/java/io/renren/ApiApplication.java create mode 100644 renren-api/src/main/java/io/renren/annotation/Login.java create mode 100644 renren-api/src/main/java/io/renren/annotation/LoginUser.java create mode 100644 renren-api/src/main/java/io/renren/config/FilterConfig.java create mode 100644 renren-api/src/main/java/io/renren/config/MybatisPlusConfig.java create mode 100644 renren-api/src/main/java/io/renren/config/SwaggerConfig.java create mode 100644 renren-api/src/main/java/io/renren/config/WebMvcConfig.java create mode 100644 renren-api/src/main/java/io/renren/controller/ApiLoginController.java create mode 100644 renren-api/src/main/java/io/renren/controller/ApiRegisterController.java create mode 100644 renren-api/src/main/java/io/renren/controller/ApiTestController.java create mode 100644 renren-api/src/main/java/io/renren/dao/TokenDao.java create mode 100644 renren-api/src/main/java/io/renren/dao/UserDao.java create mode 100644 renren-api/src/main/java/io/renren/dto/LoginDTO.java create mode 100644 renren-api/src/main/java/io/renren/dto/RegisterDTO.java create mode 100644 renren-api/src/main/java/io/renren/entity/TokenEntity.java create mode 100644 renren-api/src/main/java/io/renren/entity/UserEntity.java create mode 100644 renren-api/src/main/java/io/renren/exception/RenExceptionHandler.java create mode 100644 renren-api/src/main/java/io/renren/interceptor/AuthorizationInterceptor.java create mode 100644 renren-api/src/main/java/io/renren/resolver/LoginUserHandlerMethodArgumentResolver.java create mode 100644 renren-api/src/main/java/io/renren/service/TokenService.java create mode 100644 renren-api/src/main/java/io/renren/service/UserService.java create mode 100644 renren-api/src/main/java/io/renren/service/impl/TokenServiceImpl.java create mode 100644 renren-api/src/main/java/io/renren/service/impl/UserServiceImpl.java create mode 100644 renren-api/src/main/resources/application-dev.yml create mode 100644 renren-api/src/main/resources/application-prod.yml create mode 100644 renren-api/src/main/resources/application-test.yml create mode 100644 renren-api/src/main/resources/application.yml create mode 100644 renren-api/src/main/resources/banner.txt create mode 100644 renren-api/src/main/resources/logback-spring.xml create mode 100644 renren-api/src/main/resources/mapper/TokenDao.xml create mode 100644 renren-api/src/main/resources/mapper/UserDao.xml create mode 100644 renren-common/pom.xml create mode 100644 renren-common/src/main/java/io/renren/common/aspect/RedisAspect.java create mode 100644 renren-common/src/main/java/io/renren/common/constant/Constant.java create mode 100644 renren-common/src/main/java/io/renren/common/convert/DateConverter.java create mode 100644 renren-common/src/main/java/io/renren/common/dao/BaseDao.java create mode 100644 renren-common/src/main/java/io/renren/common/entity/BaseEntity.java create mode 100644 renren-common/src/main/java/io/renren/common/exception/ErrorCode.java create mode 100644 renren-common/src/main/java/io/renren/common/exception/ExceptionUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/exception/RenException.java create mode 100644 renren-common/src/main/java/io/renren/common/page/PageData.java create mode 100644 renren-common/src/main/java/io/renren/common/redis/RedisConfig.java create mode 100644 renren-common/src/main/java/io/renren/common/redis/RedisKeys.java create mode 100644 renren-common/src/main/java/io/renren/common/redis/RedisUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/service/BaseService.java create mode 100644 renren-common/src/main/java/io/renren/common/service/CrudService.java create mode 100644 renren-common/src/main/java/io/renren/common/service/impl/BaseServiceImpl.java create mode 100644 renren-common/src/main/java/io/renren/common/service/impl/CrudServiceImpl.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/ConvertUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/DateUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/HttpContextUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/IpUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/JsonUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/MessageUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/Result.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/SpringContextUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/TreeNode.java create mode 100644 renren-common/src/main/java/io/renren/common/utils/TreeUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/validator/AssertUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/validator/ValidatorUtils.java create mode 100644 renren-common/src/main/java/io/renren/common/validator/group/AddGroup.java create mode 100644 renren-common/src/main/java/io/renren/common/validator/group/DefaultGroup.java create mode 100644 renren-common/src/main/java/io/renren/common/validator/group/Group.java create mode 100644 renren-common/src/main/java/io/renren/common/validator/group/UpdateGroup.java create mode 100644 renren-common/src/main/java/io/renren/common/xss/SqlFilter.java create mode 100644 renren-common/src/main/java/io/renren/common/xss/XssFilter.java create mode 100644 renren-common/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java create mode 100644 renren-common/src/main/java/io/renren/common/xss/XssUtils.java create mode 100644 renren-common/src/main/resources/i18n/messages.properties create mode 100644 renren-common/src/main/resources/i18n/validation.properties create mode 100644 renren-dynamic-datasource/pom.xml create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/annotation/DataSource.java create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/aspect/DataSourceAspect.java create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicContextHolder.java create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSource.java create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceConfig.java create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceFactory.java create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DataSourceProperties.java create mode 100644 renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DynamicDataSourceProperties.java create mode 100644 renren-generator/pom.xml create mode 100644 renren-generator/src/main/java/io/renren/GeneratorApplication.java create mode 100644 renren-generator/src/main/java/io/renren/config/DbConfig.java create mode 100644 renren-generator/src/main/java/io/renren/controller/SysGeneratorController.java create mode 100644 renren-generator/src/main/java/io/renren/dao/GeneratorDao.java create mode 100644 renren-generator/src/main/java/io/renren/dao/MySQLGeneratorDao.java create mode 100644 renren-generator/src/main/java/io/renren/dao/OracleGeneratorDao.java create mode 100644 renren-generator/src/main/java/io/renren/dao/PostgreSQLGeneratorDao.java create mode 100644 renren-generator/src/main/java/io/renren/dao/SQLServerGeneratorDao.java create mode 100644 renren-generator/src/main/java/io/renren/entity/ColumnEntity.java create mode 100644 renren-generator/src/main/java/io/renren/entity/TableEntity.java create mode 100644 renren-generator/src/main/java/io/renren/service/SysGeneratorService.java create mode 100644 renren-generator/src/main/java/io/renren/utils/Assert.java create mode 100644 renren-generator/src/main/java/io/renren/utils/DateUtils.java create mode 100644 renren-generator/src/main/java/io/renren/utils/GenUtils.java create mode 100644 renren-generator/src/main/java/io/renren/utils/IdWorker.java create mode 100644 renren-generator/src/main/java/io/renren/utils/PageUtils.java create mode 100644 renren-generator/src/main/java/io/renren/utils/Query.java create mode 100644 renren-generator/src/main/java/io/renren/utils/R.java create mode 100644 renren-generator/src/main/java/io/renren/utils/RenException.java create mode 100644 renren-generator/src/main/java/io/renren/utils/RenExceptionHandler.java create mode 100644 renren-generator/src/main/java/io/renren/utils/Sequence.java create mode 100644 renren-generator/src/main/java/io/renren/utils/StringPool.java create mode 100644 renren-generator/src/main/java/io/renren/utils/SystemClock.java create mode 100644 renren-generator/src/main/resources/application.yml create mode 100644 renren-generator/src/main/resources/generator.properties create mode 100644 renren-generator/src/main/resources/logback-spring.xml create mode 100644 renren-generator/src/main/resources/mapper/MySQLGeneratorDao.xml create mode 100644 renren-generator/src/main/resources/mapper/OracleGeneratorDao.xml create mode 100644 renren-generator/src/main/resources/mapper/PostgreSQLGeneratorDao.xml create mode 100644 renren-generator/src/main/resources/mapper/SQLServerGeneratorDao.xml create mode 100644 renren-generator/src/main/resources/static/css/AdminLTE.min.css create mode 100644 renren-generator/src/main/resources/static/css/all-skins.min.css create mode 100644 renren-generator/src/main/resources/static/css/bootstrap.min.css create mode 100644 renren-generator/src/main/resources/static/css/font-awesome.min.css create mode 100644 renren-generator/src/main/resources/static/css/main.css create mode 100644 renren-generator/src/main/resources/static/favicon.ico create mode 100644 renren-generator/src/main/resources/static/fonts/FontAwesome.otf create mode 100644 renren-generator/src/main/resources/static/fonts/fontawesome-webfont.eot create mode 100644 renren-generator/src/main/resources/static/fonts/fontawesome-webfont.svg create mode 100644 renren-generator/src/main/resources/static/fonts/fontawesome-webfont.ttf create mode 100644 renren-generator/src/main/resources/static/fonts/fontawesome-webfont.woff create mode 100644 renren-generator/src/main/resources/static/fonts/fontawesome-webfont.woff2 create mode 100644 renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.eot create mode 100644 renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.svg create mode 100644 renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.ttf create mode 100644 renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.woff create mode 100644 renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 renren-generator/src/main/resources/static/js/common.js create mode 100644 renren-generator/src/main/resources/static/js/generator.js create mode 100644 renren-generator/src/main/resources/static/js/index.js create mode 100644 renren-generator/src/main/resources/static/libs/app.js create mode 100644 renren-generator/src/main/resources/static/libs/app.min.js create mode 100644 renren-generator/src/main/resources/static/libs/bootstrap.min.js create mode 100644 renren-generator/src/main/resources/static/libs/fastclick.min.js create mode 100644 renren-generator/src/main/resources/static/libs/jquery.min.js create mode 100644 renren-generator/src/main/resources/static/libs/jquery.slimscroll.min.js create mode 100644 renren-generator/src/main/resources/static/libs/router.js create mode 100644 renren-generator/src/main/resources/static/libs/vue.min.js create mode 100644 renren-generator/src/main/resources/static/plugins/jqgrid/grid.locale-cn.js create mode 100644 renren-generator/src/main/resources/static/plugins/jqgrid/jquery.jqGrid.min.js create mode 100644 renren-generator/src/main/resources/static/plugins/jqgrid/ui.jqgrid-bootstrap-ui.css create mode 100644 renren-generator/src/main/resources/static/plugins/jqgrid/ui.jqgrid-bootstrap.css create mode 100644 renren-generator/src/main/resources/static/plugins/jqgrid/ui.jqgrid.css create mode 100644 renren-generator/src/main/resources/static/plugins/layer/layer.js create mode 100644 renren-generator/src/main/resources/static/plugins/layer/mobile/layer.js create mode 100644 renren-generator/src/main/resources/static/plugins/layer/mobile/need/layer.css create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/default/icon-ext.png create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/default/icon.png create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/default/layer.css create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/default/loading-0.gif create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/default/loading-1.gif create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/default/loading-2.gif create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/moon/default.png create mode 100644 renren-generator/src/main/resources/static/plugins/layer/skin/moon/style.css create mode 100644 renren-generator/src/main/resources/template/Controller.java.vm create mode 100644 renren-generator/src/main/resources/template/DTO.java.vm create mode 100644 renren-generator/src/main/resources/template/Dao.java.vm create mode 100644 renren-generator/src/main/resources/template/Dao.xml.vm create mode 100644 renren-generator/src/main/resources/template/Entity.java.vm create mode 100644 renren-generator/src/main/resources/template/Excel.java.vm create mode 100644 renren-generator/src/main/resources/template/Service.java.vm create mode 100644 renren-generator/src/main/resources/template/ServiceImpl.java.vm create mode 100644 renren-generator/src/main/resources/template/add-or-update.vue.vm create mode 100644 renren-generator/src/main/resources/template/index.vue.vm create mode 100644 renren-generator/src/main/resources/template/mysql.vm create mode 100644 renren-generator/src/main/resources/template/oracle.vm create mode 100644 renren-generator/src/main/resources/template/postgresql.vm create mode 100644 renren-generator/src/main/resources/template/sqlserver.vm create mode 100644 renren-generator/src/main/resources/views/generator.html create mode 100644 renren-generator/src/main/resources/views/index.html create mode 100644 renren-generator/src/main/resources/views/main.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..631d03f --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ +target + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar +*.iml +.idea + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..15625aa --- /dev/null +++ b/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "{}" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright 2018 人人开源 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..50ca81b --- /dev/null +++ b/README.md @@ -0,0 +1,128 @@ +### 项目说明 +- renren-security是一个轻量级的,前后端分离的Java快速开发平台,能快速开发项目并交付【接私活利器】 +- 采用SpringBoot、Shiro、MyBatis-Plus框架,开发的一套权限系统,极低门槛,拿来即用。设计之初,就非常注重安全性,为企业系统保驾护航,让一切都变得如此简单。 +- 提供了代码生成器,只需编写30%左右代码,其余的代码交给系统自动生成,可快速完成开发任务 +- 支持MySQL、达梦、Oracle、SQL Server、PostgreSQL等主流数据库 +- 前端地址:https://gitee.com/renrenio/renren-ui +- 演示地址:http://demo.open.renren.io/renren-security (账号密码:admin/admin) + +
+ +### 微信交流群 +我们提供了微信交流群,扫码下面的二维码,关注【人人开源】公众号,回复【加群】,即可根据提示加入微信群! +

+![输入图片说明](renren-admin/src/main/resources/public/wechat.jpg) + +
+ +### 具有如下特点 +- 友好的代码结构及注释,便于阅读及二次开发 +- 实现前后端分离,通过token进行数据交互,前端再也不用关注后端技术 +- 灵活的权限控制,可控制到页面或按钮,满足绝大部分的权限需求 +- 提供CrudService接口,对增删改查进行封装,代码更简洁 +- 页面交互使用Vue2.x,极大的提高了开发效率 +- 完善的部门管理及数据权限,通过注解实现数据权限的控制 +- 完善的XSS防范及脚本过滤,彻底杜绝XSS攻击 +- 完善的代码生成机制,可在线生成entity、xml、dao、service、vue、sql代码,减少70%以上的开发任务 +- 引入quartz定时任务,可动态完成任务的添加、修改、删除、暂停、恢复及日志查看等功能 +- 引入Hibernate Validator校验框架,轻松实现后端校验 +- 引入云存储服务,已支持:七牛云、阿里云、腾讯云等 +- 引入swagger文档支持,方便编写API接口文档 + +
+ +### 数据权限设计思想 +- 用户管理、角色管理、部门管理,可操作本部门及子部门数据 +- 菜单管理、定时任务、参数管理、字典管理、系统日志,没有数据权限 +- 业务功能,按照用户数据权限,查询、操作数据【没有本部门数据权限,也能查询本人数据】 + +
+ + +**项目结构** +``` +renren-security +├─renren-common 公共模块 +│ +├─renren-admin 管理后台 +│ ├─db 数据库SQL脚本 +│ │ +│ ├─modules 模块 +│ │ ├─job 定时任务 +│ │ ├─log 日志管理 +│ │ ├─oss 文件存储 +│ │ ├─security 安全模块 +│ │ └─sys 系统管理(核心) +│ │ +│ └─resources +│ ├─mapper MyBatis文件 +│ ├─public 静态资源 +│ └─application.yml 全局配置文件 +│ +│ +├─renren-api API服务 +│ +├─renren-generator 代码生成器 +│ └─resources +│ ├─mapper MyBatis文件 +│ ├─template 代码生成器模板(可增加或修改相应模板) +│ ├─application.yml 全局配置文件 +│ └─generator.properties 代码生成器,配置文件 +│ +``` + +
+ +**技术选型:** +- 核心框架:Spring Boot 2.7 +- 安全框架:Apache Shiro 1.10 +- 持久层框架:MyBatis 3.5 +- 定时器:Quartz 2.3 +- 数据库连接池:Druid 1.2 +- 日志管理:Logback +- 页面交互:Vue2.x + +
+ +**软件需求** +- JDK1.8 +- Maven3.0+ +- MySQL8.0 +- Oracle 11g+ +- SQL Server 2012+ +- PostgreSQL 9.4+ +- 达梦8 +
+ + +**本地部署** +- 通过git下载源码 +- idea、eclipse需安装lombok插件,不然会提示找不到entity的get set方法 +- 创建数据库renren_security,数据库编码为UTF-8 +- 执行db/mysql.sql文件,初始化数据 +- 修改application-dev.yml文件,更新MySQL账号和密码 +- 在renren-security目录下,执行mvn clean install +- Eclipse、IDEA运行AdminApplication.java,则可启动项目【renren-admin】 +- renren-admin访问路径:http://localhost:8080/renren-admin +- swagger文档路径:http://localhost:8080/renren-admin/doc.html +- 再启动前端项目,前端地址:https://gitee.com/renrenio/renren-ui +- 账号密码:admin/admin +
+ +![输入图片说明](renren-admin/src/main/resources/public/1.png) + +
+ +![输入图片说明](renren-admin/src/main/resources/public/2.png) + +
+ +### 如何交流、反馈、参与贡献? +- 开发文档:https://www.renren.io/guide/security +- 官方社区:https://www.renren.io/community +- Gitee仓库:https://gitee.com/renrenio/renren-security +- [人人开源](https://www.renren.io):https://www.renren.io +- 如需关注项目最新动态,请Watch、Star项目,同时也是对项目最好的支持 +- 技术讨论、二次开发等咨询、问题和建议,请移步到官方社区,我会在第一时间进行解答和回复! +
+ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f01e567 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: '2' +services: + renren-admin: + image: renren/renren-admin + ports: + - "8080:8080" + environment: + - spring.profiles.active=dev + renren-api: + image: renren/renren-api + ports: + - "8081:8081" + environment: + - spring.profiles.active=dev \ No newline at end of file diff --git a/mt_db.sql b/mt_db.sql new file mode 100644 index 0000000..8cd2539 --- /dev/null +++ b/mt_db.sql @@ -0,0 +1,1080 @@ +/* + Navicat Premium Data Transfer + + Source Server : MySQL80 + Source Server Type : MySQL + Source Server Version : 80026 + Source Host : localhost:3306 + Source Schema : mt_db + + Target Server Type : MySQL + Target Server Version : 80026 + File Encoding : 65001 + + Date: 14/06/2023 15:38:46 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for address_book +-- ---------------------------- +DROP TABLE IF EXISTS `address_book`; +CREATE TABLE `address_book` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` bigint(0) NOT NULL COMMENT '用户id', + `consignee` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '收货人', + `gender` tinyint(0) NOT NULL COMMENT '性别 0 男 1 女', + `phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '手机号', + `province_code` varchar(12) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '省级区划编号', + `province_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '省级名称', + `city_code` varchar(12) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '市级区划编号', + `city_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '市级名称', + `district_code` varchar(12) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '区级区划编号', + `district_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '区级名称', + `detail` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '详细地址', + `label` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '标签', + `is_default` tinyint(1) NOT NULL DEFAULT 0 COMMENT '默认 0 否 1是', + `creator` bigint(0) NOT NULL COMMENT '创建人', + `create_date` datetime(0) NOT NULL COMMENT '创建时间', + `updater` bigint(0) NOT NULL COMMENT '修改人', + `update_date` datetime(0) NOT NULL COMMENT '更新时间', + `is_deleted` int(0) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '地址管理' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of address_book +-- ---------------------------- +INSERT INTO `address_book` VALUES (1, 1668247645219012609, '1111', 1, '15625658458', NULL, NULL, NULL, NULL, NULL, NULL, '25', '公司', 1, 1668247645219012609, '2023-06-14 12:56:55', 1668247645219012609, '2023-06-14 13:34:19', 0); + +-- ---------------------------- +-- Table structure for category +-- ---------------------------- +DROP TABLE IF EXISTS `category`; +CREATE TABLE `category` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `type` int(0) NULL DEFAULT NULL COMMENT '类型 1 菜品分类 2 套餐分类', + `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '分类名称', + `sort` int(0) NOT NULL DEFAULT 0 COMMENT '顺序', + `creator` bigint(0) NOT NULL COMMENT '创建人', + `create_date` datetime(0) NOT NULL COMMENT '创建时间', + `updater` bigint(0) NOT NULL COMMENT '修改人', + `update_date` datetime(0) NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_category_name`(`name`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜品及套餐分类' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of category +-- ---------------------------- +INSERT INTO `category` VALUES (1523221549476327425, 1, '家常菜', 9, 1, '2022-05-08 16:41:32', 1, '2022-05-08 17:38:00'); +INSERT INTO `category` VALUES (1523221580623228930, 1, '盖饭', 8, 1, '2022-05-08 16:41:40', 1, '2022-05-08 17:38:08'); +INSERT INTO `category` VALUES (1523221607961702401, 1, '特色菜', 7, 1, '2022-05-08 16:41:46', 1, '2022-05-08 17:38:16'); +INSERT INTO `category` VALUES (1523221632653570050, 1, '干锅', 6, 1, '2022-05-08 16:41:52', 1, '2022-05-08 17:38:22'); +INSERT INTO `category` VALUES (1523221667613093889, 1, '家常菜系列', 5, 1, '2022-05-08 16:42:00', 1, '2022-05-08 16:42:00'); +INSERT INTO `category` VALUES (1523221692862803970, 1, '汤菜', 4, 1, '2022-05-08 16:42:06', 1, '2022-05-08 17:38:34'); +INSERT INTO `category` VALUES (1523223881484185602, 1, '素菜系', 3, 1, '2022-05-08 16:50:48', 1, '2022-05-08 17:38:46'); +INSERT INTO `category` VALUES (1523224049252151297, 2, '套餐', 2, 1, '2022-05-08 16:51:28', 1, '2022-05-08 17:39:08'); +INSERT INTO `category` VALUES (1523224111688560641, 1, '米饭', 8, 1, '2022-05-08 16:51:43', 1, '2022-05-08 16:51:43'); +INSERT INTO `category` VALUES (1523224134312636417, 1, '饮料', 1, 1, '2022-05-08 16:51:48', 1, '2022-05-08 17:39:13'); + +-- ---------------------------- +-- Table structure for dish +-- ---------------------------- +DROP TABLE IF EXISTS `dish`; +CREATE TABLE `dish` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '菜品名称', + `category_id` bigint(0) NOT NULL COMMENT '菜品分类id', + `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '菜品价格', + `code` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '商品码', + `image` varchar(200) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '图片', + `description` varchar(400) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '描述信息', + `status` int(0) NOT NULL DEFAULT 1 COMMENT '0 停售 1 起售', + `sort` int(0) NOT NULL DEFAULT 0 COMMENT '顺序', + `creator` bigint(0) NOT NULL COMMENT '创建人', + `create_date` datetime(0) NOT NULL COMMENT '创建时间', + `updater` bigint(0) NOT NULL COMMENT '修改人', + `update_date` datetime(0) NOT NULL COMMENT '更新时间', + `is_deleted` int(0) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_dish_name`(`name`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜品管理' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of dish +-- ---------------------------- +INSERT INTO `dish` VALUES (1523227188311207938, '三鲜肉炒莲白(米饭单点)', 1523221549476327425, 1488.00, '001', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0a3b3288-3446-4420-bbff-f263d0c02d8e.jpg', '原料:猪肉,白菜', 1, 0, 1, '2022-06-19 14:24:07', 1559815019674214402, '2022-08-21 12:33:20', 0); +INSERT INTO `dish` VALUES (1523227597964685314, '土豆炒肉丝(米饭单点)', 1523221549476327425, 1388.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0f4bd884-dc9c-4cf9-b59e-7d5958fec3dd.jpg', '原料:土豆,猪肉', 1, 0, 1, '2022-06-19 14:24:44', 1, '2022-06-19 14:24:44', 0); +INSERT INTO `dish` VALUES (1523227696245616641, '农家炒腊肉(米饭单点)', 1523221549476327425, 1688.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0f252364-a561-4e8d-8065-9a6797a6b1d3.jpg', '原料:腊肉', 1, 0, 1, '2022-06-19 14:23:55', 1, '2022-06-19 14:23:55', 0); +INSERT INTO `dish` VALUES (1523229046501126146, '干烧鲫鱼(米饭单点)', 1523221549476327425, 1898.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/1fdbfbf3-1d86-4b29-a3fc-46345852f2f8.jpg', '原料:鲫鱼', 1, 0, 1, '2022-06-19 14:23:21', 1, '2022-06-19 14:23:21', 0); +INSERT INTO `dish` VALUES (1523229349560561666, '小炒肉(米饭单点)', 1523221549476327425, 1380.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/02b533f2f4dd038058a9bb40827ab30a.jpeg', '原料:猪肉', 1, 0, 1, '2022-06-19 14:24:31', 1, '2022-06-19 14:24:31', 0); +INSERT INTO `dish` VALUES (1523229489490931714, '尖椒鸡(米饭单点)', 1523221549476327425, 1398.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/2a2e9d66-b41d-4645-87bd-95f2cfeed218.jpg', '原料:辣椒,鸡肉', 1, 0, 1, '2022-06-19 14:23:02', 1, '2022-06-19 14:23:02', 0); +INSERT INTO `dish` VALUES (1523229659871948801, '回锅肉(米饭单点)', 1523221549476327425, 1388.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/2a50628e-7758-4c51-9fbb-d37c61cdacad.jpg', '原料:猪肉', 1, 0, 1, '2022-06-19 14:22:43', 1, '2022-06-19 14:22:43', 0); +INSERT INTO `dish` VALUES (1523229839321051137, '鱼香肉丝(米饭单点)', 1523221549476327425, 1398.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/2e96a7e3-affb-438e-b7c3-e1430df425c9.jpeg', '原料:胡罗卜、笋、木耳、猪肉', 1, 0, 1, '2022-06-19 14:21:32', 1, '2022-06-19 14:21:32', 0); +INSERT INTO `dish` VALUES (1523230006640226306, '土豆肉丝+米饭', 1523221580623228930, 1500.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/3fabb83a-1c09-4fd9-892b-4ef7457daafa.jpeg', '原料:大米、土豆、猪肉', 1, 0, 1, '2022-06-19 14:21:00', 1, '2022-06-19 14:21:00', 0); +INSERT INTO `dish` VALUES (1523230157148631041, '盐煎肉+米饭', 1523221580623228930, 1500.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/5b8d2da3-3744-4bb3-acdc-329056b8259d.jpeg', '原料:大米、猪肉、食盐', 1, 0, 1, '2022-06-19 14:20:48', 1, '2022-06-19 14:20:48', 0); +INSERT INTO `dish` VALUES (1523230305597632513, '回锅肉+米饭', 1523221580623228930, 1500.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/8dcfda14-5712-4d28-82f7-ae905b3c2308.jpg', '原料:大米、猪肉', 1, 0, 1, '2022-06-19 14:20:34', 1, '2022-06-19 14:20:34', 0); +INSERT INTO `dish` VALUES (1523230460363255810, '豆干肉丝+米饭', 1523221580623228930, 1500.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/9ec6fc2d-50d2-422e-b954-de87dcd04198.jpeg', '原料:大米、豆干、猪肉', 1, 0, 1, '2022-06-19 14:15:41', 1, '2022-06-19 14:15:41', 0); +INSERT INTO `dish` VALUES (1523230566508507138, '鱼香肉丝+米饭', 1523221580623228930, 1500.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/057dd338-e487-4bbc-a74c-0384c44a9ca3.jpg', '原料:大米、猪肉', 1, 0, 1, '2022-06-19 14:21:45', 1, '2022-06-19 14:21:45', 0); +INSERT INTO `dish` VALUES (1523230706002669569, '老盐菜炒回锅肉(米饭单点)', 1523221607961702401, 1398.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/583df4b7-a159-4cfc-9543-4f666120b25f.jpeg', '原料:猪肉', 1, 0, 1, '2022-06-19 14:14:49', 1, '2022-06-19 14:14:49', 0); +INSERT INTO `dish` VALUES (1523230887100133378, '剁椒鲫鱼(米饭单点)', 1523221607961702401, 2198.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/646d357d11812f9479e50e41651e8946.jpeg', '原料:鲫鱼', 1, 0, 1, '2022-06-19 14:14:37', 1, '2022-06-19 14:14:37', 0); +INSERT INTO `dish` VALUES (1523231074837180418, '泡椒儿肠(米饭单点)', 1523221607961702401, 1698.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/740c79ce-af29-41b8-b78d-5f49c96e38c4.jpg', '原料:猪小肠', 1, 0, 1, '2022-06-19 14:13:31', 1, '2022-06-19 14:13:31', 0); +INSERT INTO `dish` VALUES (1523231271495512066, '干锅鸡+米饭', 1523221632653570050, 1980.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/1405081e-f545-42e1-86a2-f7559ae2e276.jpeg', '原料:鸡肉', 1, 0, 1, '2022-06-19 14:19:42', 1, '2022-06-19 14:19:42', 0); +INSERT INTO `dish` VALUES (1523231432867164162, '豆花+油碟+米饭', 1523221667613093889, 980.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/a53a4e6a-3b83-4044-87f9-9d49b30a8fdc.jpg', '原料:豆腐脑', 1, 0, 1, '2022-06-19 14:11:32', 1, '2022-06-19 14:11:32', 0); +INSERT INTO `dish` VALUES (1523231582276661250, '干烧鲫鱼(不含米饭)', 1523221667613093889, 1898.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/d2f61d70-ac85-4529-9b74-6d9a2255c6d7.jpg', '原料:鲫鱼', 1, 0, 1, '2022-06-19 14:14:14', 1, '2022-06-19 14:14:14', 0); +INSERT INTO `dish` VALUES (1523231728100028417, '红烧肉(不含米饭)', 1523221667613093889, 1498.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/d1688fe2a91cda424852b88dd5f2679e.jpeg', '原料:土豆、猪肉', 1, 0, 1, '2022-06-19 14:18:42', 1, '2022-06-19 14:18:42', 0); +INSERT INTO `dish` VALUES (1523231842168320002, '土豆烧鸡(不含米饭)', 1523221667613093889, 2000.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/e476f679-5c15-436b-87fa-8c4e9644bf33.jpeg', '原料:土豆、鸡肉', 1, 0, 1, '2022-06-19 14:18:20', 1, '2022-06-19 14:18:20', 0); +INSERT INTO `dish` VALUES (1523231978755829761, '农家炒香肠(不含米饭)', 1523221667613093889, 1698.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/ef2b73f2-75d1-4d3a-beea-22da0e1421bd.jpg', '原料:香肠', 1, 0, 1, '2022-06-19 14:11:18', 1, '2022-06-19 14:11:18', 0); +INSERT INTO `dish` VALUES (1523232102403911681, '三线莲白(不含米饭)', 1523221667613093889, 1398.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/f966a38e-0780-40be-bb52-5699d13cb3d9.jpg', '原料:大白菜', 1, 0, 1, '2022-06-19 14:18:03', 1, '2022-06-19 14:18:03', 0); +INSERT INTO `dish` VALUES (1523232185912504321, '紫菜蛋花汤(不含米饭)', 1523221692862803970, 880.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0a3b3288-3446-4420-bbff-f263d0c02d8e.jpg', '原料:紫菜、鸡蛋', 1, 0, 1, '2022-06-19 14:08:47', 1, '2022-06-19 14:08:47', 0); +INSERT INTO `dish` VALUES (1523232325142425601, '酸菜粉丝汤(不含米饭)', 1523221692862803970, 780.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0f4bd884-dc9c-4cf9-b59e-7d5958fec3dd.jpg', '原料:粉丝、酸菜', 1, 0, 1, '2022-06-19 14:08:17', 1, '2022-06-19 14:08:17', 0); +INSERT INTO `dish` VALUES (1523232409104003074, '肉片汤(不含米饭)', 1523221692862803970, 2200.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0f252364-a561-4e8d-8065-9a6797a6b1d3.jpg', '原料:猪肉', 1, 0, 1, '2022-06-19 14:08:07', 1, '2022-06-19 14:08:07', 0); +INSERT INTO `dish` VALUES (1523232518197850114, '番茄鸡蛋汤(不含米饭)', 1523221692862803970, 880.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/1fdbfbf3-1d86-4b29-a3fc-46345852f2f8.jpg', '原料:番茄、 鸡蛋', 1, 0, 1, '2022-06-19 14:05:51', 1, '2022-06-19 14:05:51', 0); +INSERT INTO `dish` VALUES (1523232652012924930, '红烧茄子(不含米饭)', 1523223881484185602, 856.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/02b533f2f4dd038058a9bb40827ab30a.jpeg', '原料:茄子', 1, 0, 1, '2022-06-19 14:16:27', 1, '2022-06-19 14:16:27', 0); +INSERT INTO `dish` VALUES (1523232750734258177, '炒胡豆(不含米饭)', 1523223881484185602, 788.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/2a2e9d66-b41d-4645-87bd-95f2cfeed218.jpg', '原料:胡豆', 1, 0, 1, '2022-06-19 14:06:59', 1, '2022-06-19 14:06:59', 0); +INSERT INTO `dish` VALUES (1523232846934814722, '干煸土豆丝(不含米饭)', 1523223881484185602, 1500.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/2a50628e-7758-4c51-9fbb-d37c61cdacad.jpg', '原料:土豆', 1, 0, 1, '2022-06-19 14:07:10', 1, '2022-06-19 14:07:10', 0); +INSERT INTO `dish` VALUES (1523233237814587394, '红苕稀饭', 1523224111688560641, 168.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png', '原料:大米', 1, 0, 1, '2022-06-19 14:07:19', 1067246875800000001, '2022-08-29 21:20:05', 0); +INSERT INTO `dish` VALUES (1523233316415844354, '香肠炒饭', 1523224111688560641, 998.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png', '原料:大米、香肠', 1, 0, 1, '2022-06-19 14:07:41', 1067246875800000001, '2022-08-29 21:20:05', 0); +INSERT INTO `dish` VALUES (1523233498566078465, '鸡蛋炒饭', 1523224111688560641, 688.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png', '原料:大米、鸡蛋', 1, 0, 1, '2022-06-19 14:07:54', 1067246875800000001, '2022-08-29 21:20:05', 0); +INSERT INTO `dish` VALUES (1523233618137296897, '珍珠米饭', 1523224111688560641, 100.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png', '原料:大米', 1, 0, 1, '2022-06-19 02:47:24', 1067246875800000001, '2022-08-29 21:20:05', 0); +INSERT INTO `dish` VALUES (1523233739667255298, '怡宝', 1523224134312636417, 200.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png', '原料:水', 1, 0, 1, '2022-06-19 14:04:00', 1067246875800000001, '2022-08-29 21:20:05', 0); +INSERT INTO `dish` VALUES (1560651286804705282, 'test测试1', 1523221549476327425, 1980.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/057dd338-e487-4bbc-a74c-0384c44a9ca3.jpg', '测试测试', 1, 0, 1067246875800000001, '2022-08-19 23:33:57', 1067246875800000001, '2022-08-29 23:19:07', 0); +INSERT INTO `dish` VALUES (1564251465613164545, '测试测试', 1523221549476327425, 1100.00, '', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/583df4b7-a159-4cfc-9543-4f666120b25f.jpeg', '', 1, 0, 1067246875800000001, '2022-08-29 21:59:46', 1067246875800000001, '2022-08-29 23:18:45', 0); + +-- ---------------------------- +-- Table structure for dish_flavor +-- ---------------------------- +DROP TABLE IF EXISTS `dish_flavor`; +CREATE TABLE `dish_flavor` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `dish_id` bigint(0) NOT NULL COMMENT '菜品', + `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '口味名称', + `value` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '口味数据list', + `creator` bigint(0) NOT NULL COMMENT '创建人', + `create_date` datetime(0) NOT NULL COMMENT '创建时间', + `updater` bigint(0) NOT NULL COMMENT '修改人', + `update_date` datetime(0) NOT NULL COMMENT '更新时间', + `is_deleted` int(0) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜品口味关系表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of dish_flavor +-- ---------------------------- +INSERT INTO `dish_flavor` VALUES (1397849417888346113, 1397849417854791681, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 09:37:27', 1, '2021-05-27 09:37:27', 0); +INSERT INTO `dish_flavor` VALUES (1397849936421761025, 1397849936404983809, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-27 09:39:30', 1, '2021-05-27 09:39:30', 0); +INSERT INTO `dish_flavor` VALUES (1397849936438538241, 1397849936404983809, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 09:39:30', 1, '2021-05-27 09:39:30', 0); +INSERT INTO `dish_flavor` VALUES (1397850630734262274, 1397850630700707841, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-27 09:42:16', 1, '2021-05-27 09:42:16', 0); +INSERT INTO `dish_flavor` VALUES (1397850630755233794, 1397850630700707841, '辣度', '[\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 09:42:16', 1, '2021-05-27 09:42:16', 0); +INSERT INTO `dish_flavor` VALUES (1397853423486414850, 1397853423461249026, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 09:53:22', 1, '2021-05-27 09:53:22', 0); +INSERT INTO `dish_flavor` VALUES (1397854133632413697, 1397854133603053569, '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', 1, '2021-05-27 09:56:11', 1, '2021-05-27 09:56:11', 0); +INSERT INTO `dish_flavor` VALUES (1397855742303186946, 1397855742273826817, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 10:02:35', 1, '2021-05-27 10:02:35', 0); +INSERT INTO `dish_flavor` VALUES (1397855906497605633, 1397855906468245506, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-27 10:03:14', 1, '2021-05-27 10:03:14', 0); +INSERT INTO `dish_flavor` VALUES (1397856190573621250, 1397856190540066818, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 10:04:21', 1, '2021-05-27 10:04:21', 0); +INSERT INTO `dish_flavor` VALUES (1397859056709316609, 1397859056684150785, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 10:15:45', 1, '2021-05-27 10:15:45', 0); +INSERT INTO `dish_flavor` VALUES (1397859277837217794, 1397859277812051969, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 10:16:37', 1, '2021-05-27 10:16:37', 0); +INSERT INTO `dish_flavor` VALUES (1397859487502086146, 1397859487476920321, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 10:17:27', 1, '2021-05-27 10:17:27', 0); +INSERT INTO `dish_flavor` VALUES (1397859757061615618, 1397859757036449794, '甜味', '[\"无糖\",\"少糖\",\"半躺\",\"多糖\",\"全糖\"]', 1, '2021-05-27 10:18:32', 1, '2021-05-27 10:18:32', 0); +INSERT INTO `dish_flavor` VALUES (1397861135754506242, 1397861135733534722, '甜味', '[\"无糖\",\"少糖\",\"半躺\",\"多糖\",\"全糖\"]', 1, '2021-05-27 10:24:00', 1, '2021-05-27 10:24:00', 0); +INSERT INTO `dish_flavor` VALUES (1397861370035744769, 1397861370010578945, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-27 10:24:56', 1, '2021-05-27 10:24:56', 0); +INSERT INTO `dish_flavor` VALUES (1397861898467717121, 1397861898438356993, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-27 10:27:02', 1, '2021-05-27 10:27:02', 0); +INSERT INTO `dish_flavor` VALUES (1398089545865015297, 1398089545676271617, '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', 1, '2021-05-28 01:31:38', 1, '2021-05-28 01:31:38', 0); +INSERT INTO `dish_flavor` VALUES (1398089782323097601, 1398089782285348866, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:32:34', 1, '2021-05-28 01:32:34', 0); +INSERT INTO `dish_flavor` VALUES (1398090003262255106, 1398090003228700673, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-28 01:33:27', 1, '2021-05-28 01:33:27', 0); +INSERT INTO `dish_flavor` VALUES (1398090264554811394, 1398090264517062657, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-28 01:34:29', 1, '2021-05-28 01:34:29', 0); +INSERT INTO `dish_flavor` VALUES (1398090455399837698, 1398090455324340225, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:35:14', 1, '2021-05-28 01:35:14', 0); +INSERT INTO `dish_flavor` VALUES (1398090685449023490, 1398090685419663362, '温度', '[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]', 1, '2021-05-28 01:36:09', 1, '2021-05-28 01:36:09', 0); +INSERT INTO `dish_flavor` VALUES (1398090825358422017, 1398090825329061889, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-28 01:36:43', 1, '2021-05-28 01:36:43', 0); +INSERT INTO `dish_flavor` VALUES (1398091007051476993, 1398091007017922561, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:37:26', 1, '2021-05-28 01:37:26', 0); +INSERT INTO `dish_flavor` VALUES (1398091296164851713, 1398091296131297281, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:38:35', 1, '2021-05-28 01:38:35', 0); +INSERT INTO `dish_flavor` VALUES (1398091546531246081, 1398091546480914433, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2021-05-28 01:39:35', 1, '2021-05-28 01:39:35', 0); +INSERT INTO `dish_flavor` VALUES (1398091729809747969, 1398091729788776450, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:40:18', 1, '2021-05-28 01:40:18', 0); +INSERT INTO `dish_flavor` VALUES (1398091889499484161, 1398091889449152513, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:40:56', 1, '2021-05-28 01:40:56', 0); +INSERT INTO `dish_flavor` VALUES (1398092095179763713, 1398092095142014978, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:41:45', 1, '2021-05-28 01:41:45', 0); +INSERT INTO `dish_flavor` VALUES (1398092283877306370, 1398092283847946241, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:42:30', 1, '2021-05-28 01:42:30', 0); +INSERT INTO `dish_flavor` VALUES (1398094018939236354, 1398094018893099009, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:49:24', 1, '2021-05-28 01:49:24', 0); +INSERT INTO `dish_flavor` VALUES (1398094391494094850, 1398094391456346113, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2021-05-28 01:50:53', 1, '2021-05-28 01:50:53', 0); +INSERT INTO `dish_flavor` VALUES (1399574026165727233, 1399305325713600514, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1399309715396669441, '2021-06-01 03:50:25', 1399309715396669441, '2021-06-01 03:50:25', 0); +INSERT INTO `dish_flavor` VALUES (1523231271495512067, 1523231271495512066, '辣度', '[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]', 1, '2022-06-19 14:19:42', 1, '2022-06-19 14:19:42', 0); +INSERT INTO `dish_flavor` VALUES (1523231582276661251, 1523231582276661250, '忌口', '[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]', 1, '2022-06-19 14:14:14', 1, '2022-06-19 14:14:14', 0); + +-- ---------------------------- +-- Table structure for order_detail +-- ---------------------------- +DROP TABLE IF EXISTS `order_detail`; +CREATE TABLE `order_detail` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '名字', + `image` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '图片', + `order_id` bigint(0) NOT NULL COMMENT '订单id', + `dish_id` bigint(0) NULL DEFAULT NULL COMMENT '菜品id', + `setmeal_id` bigint(0) NULL DEFAULT NULL COMMENT '套餐id', + `dish_flavor` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '口味', + `number` int(0) NOT NULL DEFAULT 1 COMMENT '数量', + `amount` decimal(10, 2) NOT NULL COMMENT '金额', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单明细表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of order_detail +-- ---------------------------- +INSERT INTO `order_detail` VALUES (4, '干煸土豆丝(不含米饭)', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/2a50628e-7758-4c51-9fbb-d37c61cdacad.jpg', 1668848038638575618, 1523232846934814722, NULL, NULL, 1, 15.00); +INSERT INTO `order_detail` VALUES (5, '珍珠米饭', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png', 1668848038638575618, 1523233618137296897, NULL, NULL, 1, 1.00); +INSERT INTO `order_detail` VALUES (6, '怡宝', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png', 1668848932419592194, 1523233739667255298, NULL, NULL, 1, 2.00); +INSERT INTO `order_detail` VALUES (7, '怡宝', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png', 1668849273609445377, 1523233739667255298, NULL, NULL, 1, 2.00); +INSERT INTO `order_detail` VALUES (8, '怡宝', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png', 1668850382742781953, 1523233739667255298, NULL, NULL, 1, 2.00); +INSERT INTO `order_detail` VALUES (9, '珍珠米饭', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/ee04a05a-1230-46b6-8ad5-1a95b140fff3.png', 1668851197406683137, 1523233618137296897, NULL, NULL, 1, 1.00); +INSERT INTO `order_detail` VALUES (11, '测试测试', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/e476f679-5c15-436b-87fa-8c4e9644bf33.jpeg', 1668854130919673858, NULL, 1564264362565296130, NULL, 1, 33.00); +INSERT INTO `order_detail` VALUES (13, '豆花+油碟+米饭', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/a53a4e6a-3b83-4044-87f9-9d49b30a8fdc.jpg', 1668854130919673858, 1523231432867164162, NULL, NULL, 1, 9.80); + +-- ---------------------------- +-- Table structure for orders +-- ---------------------------- +DROP TABLE IF EXISTS `orders`; +CREATE TABLE `orders` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `number` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '订单号', + `status` int(0) NOT NULL DEFAULT 1 COMMENT '订单状态 1待付款,2待派送,3已派送,4已完成,5已取消', + `user_id` bigint(0) NOT NULL COMMENT '下单用户', + `address_book_id` bigint(0) NOT NULL COMMENT '地址id', + `order_time` datetime(0) NOT NULL COMMENT '下单时间', + `checkout_time` datetime(0) NULL DEFAULT NULL COMMENT '结账时间', + `pay_method` int(0) NOT NULL DEFAULT 1 COMMENT '支付方式 1微信,2支付宝', + `amount` decimal(10, 2) NOT NULL COMMENT '实收金额', + `remark` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '备注', + `phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, + `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, + `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, + `consignee` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of orders +-- ---------------------------- +INSERT INTO `orders` VALUES (1, '1668845880056819713', 1, 1668247645219012609, 1, '2023-06-14 13:00:38', NULL, 2, 16.00, '123', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (2, '1668846627565678594', 1, 1668247645219012609, 1, '2023-06-14 13:03:36', NULL, 2, 16.00, '', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (3, '1668846813885034498', 1, 1668247645219012609, 1, '2023-06-14 13:05:26', NULL, 2, 16.00, '', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (4, '1668848038638575618', 1, 1668247645219012609, 1, '2023-06-14 13:09:13', NULL, 2, 16.00, '', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (5, '1668848932419592194', 1, 1668247645219012609, 1, '2023-06-14 13:12:46', NULL, 2, 2.00, '', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (6, '1668849273609445377', 1, 1668247645219012609, 1, '2023-06-14 13:14:07', NULL, 2, 2.00, '', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (7, '1668850382742781953', 2, 1668247645219012609, 1, '2023-06-14 13:18:32', '2023-06-14 13:18:50', 2, 2.00, '', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (8, '1668851197406683137', 2, 1668247645219012609, 1, '2023-06-14 13:21:46', '2023-06-14 13:22:00', 2, 1.00, 'test', '15625658458', '252', NULL, '1111'); +INSERT INTO `orders` VALUES (9, '1668854130919673858', 2, 1668247645219012609, 1, '2023-06-14 13:33:25', '2023-06-14 13:33:36', 2, 42.00, 'tttt', '15625658458', '252', NULL, '1111'); + +-- ---------------------------- +-- Table structure for qrtz_blob_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_blob_triggers`; +CREATE TABLE `qrtz_blob_triggers` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `BLOB_DATA` blob NULL, + PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE, + INDEX `SCHED_NAME`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE, + CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for qrtz_calendars +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_calendars`; +CREATE TABLE `qrtz_calendars` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `CALENDAR_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `CALENDAR` blob NOT NULL, + PRIMARY KEY (`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for qrtz_cron_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_cron_triggers`; +CREATE TABLE `qrtz_cron_triggers` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `CRON_EXPRESSION` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TIME_ZONE_ID` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE, + CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_cron_triggers +-- ---------------------------- +INSERT INTO `qrtz_cron_triggers` VALUES ('RenrenScheduler', 'TASK_1067246875800000076', 'DEFAULT', '0 0/30 * * * ?', 'Asia/Shanghai'); + +-- ---------------------------- +-- Table structure for qrtz_fired_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_fired_triggers`; +CREATE TABLE `qrtz_fired_triggers` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `ENTRY_ID` varchar(95) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `INSTANCE_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `FIRED_TIME` bigint(0) NOT NULL, + `SCHED_TIME` bigint(0) NOT NULL, + `PRIORITY` int(0) NOT NULL, + `STATE` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `JOB_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `JOB_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`SCHED_NAME`, `ENTRY_ID`) USING BTREE, + INDEX `IDX_QRTZ_FT_TRIG_INST_NAME`(`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE, + INDEX `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY`(`SCHED_NAME`, `INSTANCE_NAME`, `REQUESTS_RECOVERY`) USING BTREE, + INDEX `IDX_QRTZ_FT_J_G`(`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_FT_JG`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_FT_T_G`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_FT_TG`(`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for qrtz_job_details +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_job_details`; +CREATE TABLE `qrtz_job_details` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `JOB_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `JOB_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `DESCRIPTION` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `JOB_CLASS_NAME` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `IS_DURABLE` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `IS_NONCONCURRENT` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `IS_UPDATE_DATA` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `REQUESTS_RECOVERY` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `JOB_DATA` blob NULL, + PRIMARY KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_J_REQ_RECOVERY`(`SCHED_NAME`, `REQUESTS_RECOVERY`) USING BTREE, + INDEX `IDX_QRTZ_J_GRP`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_job_details +-- ---------------------------- +INSERT INTO `qrtz_job_details` VALUES ('RenrenScheduler', 'TASK_1067246875800000076', 'DEFAULT', NULL, 'io.renren.modules.job.utils.ScheduleJob', '0', '0', '0', '0', 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C7708000000100000000174000D4A4F425F504152414D5F4B45597372002E696F2E72656E72656E2E6D6F64756C65732E6A6F622E656E746974792E5363686564756C654A6F62456E7469747900000000000000010200074C00086265616E4E616D657400124C6A6176612F6C616E672F537472696E673B4C000E63726F6E45787072657373696F6E71007E00094C0006706172616D7371007E00094C000672656D61726B71007E00094C00067374617475737400134C6A6176612F6C616E672F496E74656765723B4C000A757064617465446174657400104C6A6176612F7574696C2F446174653B4C0007757064617465727400104C6A6176612F6C616E672F4C6F6E673B78720022696F2E72656E72656E2E636F6D6D6F6E2E656E746974792E42617365456E74697479FB83923222FF87B90200034C000A6372656174654461746571007E000B4C000763726561746F7271007E000C4C0002696471007E000C78707372000E6A6176612E7574696C2E44617465686A81014B59741903000078707708000001889FD0EAE8787372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700ECF9F6107B456017371007E00110ECF9F6107B4564C740008746573745461736B74000E3020302F3330202A202A202A203F74000672656E72656E740025E69C89E58F82E6B58BE8AF95EFBC8CE5A49AE4B8AAE58F82E695B0E4BDBFE794A86A736F6E737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C75657871007E0012000000007371007E000F7708000001889FD0EAE8787371007E00110ECF9F6107B456017800); + +-- ---------------------------- +-- Table structure for qrtz_locks +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_locks`; +CREATE TABLE `qrtz_locks` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `LOCK_NAME` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + PRIMARY KEY (`SCHED_NAME`, `LOCK_NAME`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_locks +-- ---------------------------- +INSERT INTO `qrtz_locks` VALUES ('RenrenScheduler', 'STATE_ACCESS'); +INSERT INTO `qrtz_locks` VALUES ('RenrenScheduler', 'TRIGGER_ACCESS'); + +-- ---------------------------- +-- Table structure for qrtz_paused_trigger_grps +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_paused_trigger_grps`; +CREATE TABLE `qrtz_paused_trigger_grps` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + PRIMARY KEY (`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for qrtz_scheduler_state +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_scheduler_state`; +CREATE TABLE `qrtz_scheduler_state` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `INSTANCE_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `LAST_CHECKIN_TIME` bigint(0) NOT NULL, + `CHECKIN_INTERVAL` bigint(0) NOT NULL, + PRIMARY KEY (`SCHED_NAME`, `INSTANCE_NAME`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_scheduler_state +-- ---------------------------- +INSERT INTO `qrtz_scheduler_state` VALUES ('RenrenScheduler', 'LAPTOP-4DMOD6O51686728211439', 1686728288954, 15000); + +-- ---------------------------- +-- Table structure for qrtz_simple_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_simple_triggers`; +CREATE TABLE `qrtz_simple_triggers` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `REPEAT_COUNT` bigint(0) NOT NULL, + `REPEAT_INTERVAL` bigint(0) NOT NULL, + `TIMES_TRIGGERED` bigint(0) NOT NULL, + PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE, + CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for qrtz_simprop_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_simprop_triggers`; +CREATE TABLE `qrtz_simprop_triggers` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `STR_PROP_1` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `STR_PROP_2` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `STR_PROP_3` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `INT_PROP_1` int(0) NULL DEFAULT NULL, + `INT_PROP_2` int(0) NULL DEFAULT NULL, + `LONG_PROP_1` bigint(0) NULL DEFAULT NULL, + `LONG_PROP_2` bigint(0) NULL DEFAULT NULL, + `DEC_PROP_1` decimal(13, 4) NULL DEFAULT NULL, + `DEC_PROP_2` decimal(13, 4) NULL DEFAULT NULL, + `BOOL_PROP_1` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `BOOL_PROP_2` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE, + CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for qrtz_triggers +-- ---------------------------- +DROP TABLE IF EXISTS `qrtz_triggers`; +CREATE TABLE `qrtz_triggers` ( + `SCHED_NAME` varchar(120) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `JOB_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `JOB_GROUP` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `DESCRIPTION` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `NEXT_FIRE_TIME` bigint(0) NULL DEFAULT NULL, + `PREV_FIRE_TIME` bigint(0) NULL DEFAULT NULL, + `PRIORITY` int(0) NULL DEFAULT NULL, + `TRIGGER_STATE` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `TRIGGER_TYPE` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, + `START_TIME` bigint(0) NOT NULL, + `END_TIME` bigint(0) NULL DEFAULT NULL, + `CALENDAR_NAME` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, + `MISFIRE_INSTR` smallint(0) NULL DEFAULT NULL, + `JOB_DATA` blob NULL, + PRIMARY KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_T_J`(`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_T_JG`(`SCHED_NAME`, `JOB_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_T_C`(`SCHED_NAME`, `CALENDAR_NAME`) USING BTREE, + INDEX `IDX_QRTZ_T_G`(`SCHED_NAME`, `TRIGGER_GROUP`) USING BTREE, + INDEX `IDX_QRTZ_T_STATE`(`SCHED_NAME`, `TRIGGER_STATE`) USING BTREE, + INDEX `IDX_QRTZ_T_N_STATE`(`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE, + INDEX `IDX_QRTZ_T_N_G_STATE`(`SCHED_NAME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE, + INDEX `IDX_QRTZ_T_NEXT_FIRE_TIME`(`SCHED_NAME`, `NEXT_FIRE_TIME`) USING BTREE, + INDEX `IDX_QRTZ_T_NFT_ST`(`SCHED_NAME`, `TRIGGER_STATE`, `NEXT_FIRE_TIME`) USING BTREE, + INDEX `IDX_QRTZ_T_NFT_MISFIRE`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`) USING BTREE, + INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`, `TRIGGER_STATE`) USING BTREE, + INDEX `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP`(`SCHED_NAME`, `MISFIRE_INSTR`, `NEXT_FIRE_TIME`, `TRIGGER_GROUP`, `TRIGGER_STATE`) USING BTREE, + CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `qrtz_job_details` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of qrtz_triggers +-- ---------------------------- +INSERT INTO `qrtz_triggers` VALUES ('RenrenScheduler', 'TASK_1067246875800000076', 'DEFAULT', 'TASK_1067246875800000076', 'DEFAULT', NULL, 1686313800000, -1, 5, 'PAUSED', 'CRON', 1686312005000, 0, NULL, 2, 0xACED0005737200156F72672E71756172747A2E4A6F62446174614D61709FB083E8BFA9B0CB020000787200266F72672E71756172747A2E7574696C732E537472696E674B65794469727479466C61674D61708208E8C3FBC55D280200015A0013616C6C6F77735472616E7369656E74446174617872001D6F72672E71756172747A2E7574696C732E4469727479466C61674D617013E62EAD28760ACE0200025A000564697274794C00036D617074000F4C6A6176612F7574696C2F4D61703B787001737200116A6176612E7574696C2E486173684D61700507DAC1C31660D103000246000A6C6F6164466163746F724900097468726573686F6C6478703F4000000000000C7708000000100000000174000D4A4F425F504152414D5F4B45597372002E696F2E72656E72656E2E6D6F64756C65732E6A6F622E656E746974792E5363686564756C654A6F62456E7469747900000000000000010200074C00086265616E4E616D657400124C6A6176612F6C616E672F537472696E673B4C000E63726F6E45787072657373696F6E71007E00094C0006706172616D7371007E00094C000672656D61726B71007E00094C00067374617475737400134C6A6176612F6C616E672F496E74656765723B4C000A757064617465446174657400104C6A6176612F7574696C2F446174653B4C0007757064617465727400104C6A6176612F6C616E672F4C6F6E673B78720022696F2E72656E72656E2E636F6D6D6F6E2E656E746974792E42617365456E74697479FB83923222FF87B90200034C000A6372656174654461746571007E000B4C000763726561746F7271007E000C4C0002696471007E000C78707372000E6A6176612E7574696C2E44617465686A81014B59741903000078707708000001889FD0EAE8787372000E6A6176612E6C616E672E4C6F6E673B8BE490CC8F23DF0200014A000576616C7565787200106A6176612E6C616E672E4E756D62657286AC951D0B94E08B02000078700ECF9F6107B456017371007E00110ECF9F6107B4564C740008746573745461736B74000E3020302F3330202A202A202A203F74000672656E72656E740025E69C89E58F82E6B58BE8AF95EFBC8CE5A49AE4B8AAE58F82E695B0E4BDBFE794A86A736F6E737200116A6176612E6C616E672E496E746567657212E2A0A4F781873802000149000576616C75657871007E0012000000007371007E000F7708000001889FD0EAE8787371007E00110ECF9F6107B456017800); + +-- ---------------------------- +-- Table structure for schedule_job +-- ---------------------------- +DROP TABLE IF EXISTS `schedule_job`; +CREATE TABLE `schedule_job` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `bean_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'spring bean名称', + `params` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '参数', + `cron_expression` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'cron表达式', + `status` tinyint unsigned NULL COMMENT '任务状态 0:暂停 1:正常', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of schedule_job +-- ---------------------------- +INSERT INTO `schedule_job` VALUES (1067246875800000076, 'testTask', 'renren', '0 0/30 * * * ?', 0, '有参测试,多个参数使用json', 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); + +-- ---------------------------- +-- Table structure for schedule_job_log +-- ---------------------------- +DROP TABLE IF EXISTS `schedule_job_log`; +CREATE TABLE `schedule_job_log` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `job_id` bigint(0) NOT NULL COMMENT '任务id', + `bean_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'spring bean名称', + `params` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '参数', + `status` tinyint unsigned NOT NULL COMMENT '任务状态 0:失败 1:成功', + `error` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '失败信息', + `times` int(0) NOT NULL COMMENT '耗时(单位:毫秒)', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_job_id`(`job_id`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务日志' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for setmeal +-- ---------------------------- +DROP TABLE IF EXISTS `setmeal`; +CREATE TABLE `setmeal` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `category_id` bigint(0) NOT NULL COMMENT '菜品分类id', + `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '套餐名称', + `price` decimal(10, 2) NOT NULL COMMENT '套餐价格', + `status` int(0) NULL DEFAULT NULL COMMENT '状态 0:停用 1:启用', + `code` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '编码', + `description` varchar(512) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '描述信息', + `image` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '图片', + `creator` bigint(0) NOT NULL COMMENT '创建人', + `create_date` datetime(0) NOT NULL COMMENT '创建时间', + `updater` bigint(0) NOT NULL COMMENT '修改人', + `update_date` datetime(0) NOT NULL COMMENT '更新时间', + `is_deleted` int(0) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `idx_setmeal_name`(`name`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '套餐' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of setmeal +-- ---------------------------- +INSERT INTO `setmeal` VALUES (1523233943468486658, 1523224049252151297, '农家腊肉+小菜+米饭', 1998.00, 1, '', '原料:大米、青菜、腊肉', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0a3b3288-3446-4420-bbff-f263d0c02d8e.jpg', 1, '2022-06-19 14:29:33', 1067246875800000001, '2022-08-29 21:19:55', 0); +INSERT INTO `setmeal` VALUES (1523234378937905154, 1523224049252151297, '农家小炒肉+小菜+米饭', 1900.00, 1, '', '原料:大米、猪肉', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0f4bd884-dc9c-4cf9-b59e-7d5958fec3dd.jpg', 1, '2022-06-19 14:29:05', 1067246875800000001, '2022-08-29 21:19:55', 0); +INSERT INTO `setmeal` VALUES (1523234624120139777, 1523224049252151297, '尖椒鸡+小菜+米饭', 1988.00, 1, '', '原料:大米、辣椒、青菜、鸡肉', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/0f252364-a561-4e8d-8065-9a6797a6b1d3.jpg', 1, '2022-06-19 14:29:17', 1067246875800000001, '2022-08-29 21:19:55', 0); +INSERT INTO `setmeal` VALUES (1564250809707905025, 1523224049252151297, '测试套餐', 5000.00, 1, '001', '测试', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/d1688fe2a91cda424852b88dd5f2679e.jpeg', 1067246875800000001, '2022-08-29 21:57:10', 1067246875800000001, '2022-08-29 22:19:58', 0); +INSERT INTO `setmeal` VALUES (1564264362565296130, 1523224049252151297, '测试测试', 3300.00, 1, '', '测试', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/e476f679-5c15-436b-87fa-8c4e9644bf33.jpeg', 1067246875800000001, '2022-08-29 21:57:10', 1067246875800000001, '2022-08-29 22:16:46', 0); + +-- ---------------------------- +-- Table structure for setmeal_dish +-- ---------------------------- +DROP TABLE IF EXISTS `setmeal_dish`; +CREATE TABLE `setmeal_dish` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `setmeal_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '套餐id ', + `dish_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '菜品id', + `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '菜品名称 (冗余字段)', + `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '菜品原价(冗余字段)', + `copies` int(0) NOT NULL COMMENT '份数', + `sort` int(0) NOT NULL DEFAULT 0 COMMENT '排序', + `creator` bigint(0) NOT NULL COMMENT '创建人', + `create_date` datetime(0) NOT NULL COMMENT '创建时间', + `updater` bigint(0) NOT NULL COMMENT '修改人', + `update_date` datetime(0) NOT NULL COMMENT '更新时间', + `is_deleted` int(0) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '套餐菜品关系' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of setmeal_dish +-- ---------------------------- +INSERT INTO `setmeal_dish` VALUES (1538408506959384577, '1523234378937905154', '1523233618137296897', '珍珠米饭', 100.00, 1, 0, 1, '2022-06-19 14:29:05', 1, '2022-06-19 14:29:05', 0); +INSERT INTO `setmeal_dish` VALUES (1538408506959384578, '1523234378937905154', '1523229349560561666', '小炒肉(米饭单点)', 1380.00, 1, 0, 1, '2022-06-19 14:29:05', 1, '2022-06-19 14:29:05', 0); +INSERT INTO `setmeal_dish` VALUES (1538408555852386305, '1523234624120139777', '1523229489490931714', '尖椒鸡(米饭单点)', 1398.00, 1, 0, 1, '2022-06-19 14:29:17', 1, '2022-06-19 14:29:17', 0); +INSERT INTO `setmeal_dish` VALUES (1538408555852386306, '1523234624120139777', '1523233618137296897', '珍珠米饭', 100.00, 1, 0, 1, '2022-06-19 14:29:17', 1, '2022-06-19 14:29:17', 0); +INSERT INTO `setmeal_dish` VALUES (1538408624433451009, '1523233943468486658', '1523233618137296897', '珍珠米饭', 100.00, 1, 0, 1, '2022-06-19 14:29:33', 1, '2022-06-19 14:29:33', 0); +INSERT INTO `setmeal_dish` VALUES (1538408624433451010, '1523233943468486658', '1523227696245616641', '农家炒腊肉(米饭单点)', 1688.00, 1, 0, 1, '2022-06-19 14:29:33', 1, '2022-06-19 14:29:33', 0); +INSERT INTO `setmeal_dish` VALUES (1564264362590461954, '1564264362565296130', '1564251465613164545', '测试测试', 1100.00, 1, 0, 1067246875800000001, '2022-08-29 22:51:01', 1067246875800000001, '2022-08-29 22:51:01', 0); + +-- ---------------------------- +-- Table structure for shopping_cart +-- ---------------------------- +DROP TABLE IF EXISTS `shopping_cart`; +CREATE TABLE `shopping_cart` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '名称', + `image` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '图片', + `user_id` bigint(0) NOT NULL COMMENT '主键', + `dish_id` bigint(0) NULL DEFAULT NULL COMMENT '菜品id', + `setmeal_id` bigint(0) NULL DEFAULT NULL COMMENT '套餐id', + `dish_flavor` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '口味', + `number` int(0) NOT NULL DEFAULT 1 COMMENT '数量', + `amount` decimal(10, 2) NOT NULL COMMENT '金额', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '购物车' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of shopping_cart +-- ---------------------------- +INSERT INTO `shopping_cart` VALUES (1523375836910018561, '干锅鸡+米饭', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/1405081e-f545-42e1-86a2-f7559ae2e276.jpeg', 1523365273903456258, 1523231271495512066, NULL, '重辣', 1, 19.80, 1523365273903456258, '2022-05-09 02:54:37', 1523365273903456258, '2022-05-09 02:54:37'); +INSERT INTO `shopping_cart` VALUES (1523375851594276865, '怡宝', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/c99e0aab-3cb7-4eaa-80fd-f47d4ffea694.png', 1523365273903456258, 1523233739667255298, NULL, NULL, 1, 2.00, 1523365273903456258, '2022-05-09 02:54:41', 1523365273903456258, '2022-05-09 02:54:41'); +INSERT INTO `shopping_cart` VALUES (1533060367050199041, '尖椒鸡(米饭单点)', 'https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/2a2e9d66-b41d-4645-87bd-95f2cfeed218.jpg', 1530789235311808513, 1523229489490931714, NULL, NULL, 1, 13.98, 1530789235311808513, '2022-06-04 20:17:29', 1530789235311808513, '2022-06-04 20:17:29'); + +-- ---------------------------- +-- Table structure for sys_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dept`; +CREATE TABLE `sys_dept` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `pid` bigint(0) NULL DEFAULT NULL COMMENT '上级ID', + `pids` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '所有上级ID,用逗号分开', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '部门名称', + `sort` int unsigned NULL COMMENT '排序', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_pid`(`pid`) USING BTREE, + INDEX `idx_sort`(`sort`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '部门管理' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dept +-- ---------------------------- +INSERT INTO `sys_dept` VALUES (1067246875800000062, 1067246875800000063, '1067246875800000066,1067246875800000063', '技术部', 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dept` VALUES (1067246875800000063, 1067246875800000066, '1067246875800000066', '长沙分公司', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dept` VALUES (1067246875800000064, 1067246875800000066, '1067246875800000066', '上海分公司', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dept` VALUES (1067246875800000065, 1067246875800000064, '1067246875800000066,1067246875800000064', '市场部', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dept` VALUES (1067246875800000066, 0, '0', '人人开源集团', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dept` VALUES (1067246875800000067, 1067246875800000064, '1067246875800000066,1067246875800000064', '销售部', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dept` VALUES (1067246875800000068, 1067246875800000063, '1067246875800000066,1067246875800000063', '产品部', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); + +-- ---------------------------- +-- Table structure for sys_dict_data +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_data`; +CREATE TABLE `sys_dict_data` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `dict_type_id` bigint(0) NOT NULL COMMENT '字典类型ID', + `dict_label` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '字典标签', + `dict_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '字典值', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `sort` int unsigned NULL COMMENT '排序', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_dict_type_value`(`dict_type_id`, `dict_value`) USING BTREE, + INDEX `idx_sort`(`sort`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '字典数据' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_data +-- ---------------------------- +INSERT INTO `sys_dict_data` VALUES (1160061112075464705, 1160061077912858625, '男', '0', '', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dict_data` VALUES (1160061146967879681, 1160061077912858625, '女', '1', '', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dict_data` VALUES (1160061190127267841, 1160061077912858625, '保密', '2', '', 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dict_data` VALUES (1225814069634195457, 1225813644059140097, '公告', '0', '', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dict_data` VALUES (1225814107559092225, 1225813644059140097, '会议', '1', '', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dict_data` VALUES (1225814271879340034, 1225813644059140097, '其他', '2', '', 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); + +-- ---------------------------- +-- Table structure for sys_dict_type +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_type`; +CREATE TABLE `sys_dict_type` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '字典类型', + `dict_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '字典名称', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `sort` int unsigned NULL COMMENT '排序', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `dict_type`(`dict_type`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '字典类型' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_type +-- ---------------------------- +INSERT INTO `sys_dict_type` VALUES (1160061077912858625, 'gender', '性别', '', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_dict_type` VALUES (1225813644059140097, 'notice_type', '站内通知-类型', '', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); + +-- ---------------------------- +-- Table structure for sys_log_error +-- ---------------------------- +DROP TABLE IF EXISTS `sys_log_error`; +CREATE TABLE `sys_log_error` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `request_uri` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求URI', + `request_method` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求方式', + `request_params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '请求参数', + `user_agent` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户代理', + `ip` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作IP', + `error_info` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '异常信息', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '异常日志' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_log_login +-- ---------------------------- +DROP TABLE IF EXISTS `sys_log_login`; +CREATE TABLE `sys_log_login` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `operation` tinyint unsigned NULL COMMENT '用户操作 0:用户登录 1:用户退出', + `status` tinyint unsigned NOT NULL COMMENT '状态 0:失败 1:成功 2:账号已锁定', + `user_agent` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户代理', + `ip` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作IP', + `creator_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_status`(`status`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '登录日志' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_log_login +-- ---------------------------- +INSERT INTO `sys_log_login` VALUES (1668885255721377794, 0, 1, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', '0:0:0:0:0:0:0:1', 'admin', 1067246875800000001, '2023-06-14 15:37:06'); + +-- ---------------------------- +-- Table structure for sys_log_operation +-- ---------------------------- +DROP TABLE IF EXISTS `sys_log_operation`; +CREATE TABLE `sys_log_operation` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `operation` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户操作', + `request_uri` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求URI', + `request_method` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '请求方式', + `request_params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '请求参数', + `request_time` int unsigned NOT NULL COMMENT '请求时长(毫秒)', + `user_agent` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户代理', + `ip` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作IP', + `status` tinyint unsigned NOT NULL COMMENT '状态 0:失败 1:成功', + `creator_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户名', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '操作日志' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_log_operation +-- ---------------------------- +INSERT INTO `sys_log_operation` VALUES (1668885397493047298, '修改', '/renren-admin/takeout/setmeal/', 'PUT', '{\"id\":1564250809707905025,\"categoryId\":1523224049252151297,\"name\":\"测试套餐\",\"price\":5000,\"status\":0,\"code\":\"001\",\"description\":\"测试\",\"image\":\"https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/d1688fe2a91cda424852b88dd5f2679e.jpeg\",\"creator\":1067246875800000001,\"createDate\":1661781430000,\"updater\":1067246875800000001,\"updateDate\":1661782798000,\"isDeleted\":0}', 18, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', '0:0:0:0:0:0:0:1', 1, 'admin', 1067246875800000001, '2023-06-14 15:37:40'); +INSERT INTO `sys_log_operation` VALUES (1668885437984858114, '修改', '/renren-admin/takeout/setmeal/', 'PUT', '{\"id\":1564250809707905025,\"categoryId\":1523224049252151297,\"name\":\"测试套餐\",\"price\":5000,\"status\":1,\"code\":\"001\",\"description\":\"测试\",\"image\":\"https://mt-take-out-1259733126.cos.ap-nanjing.myqcloud.com/d1688fe2a91cda424852b88dd5f2679e.jpeg\",\"creator\":1067246875800000001,\"createDate\":1661781430000,\"updater\":1067246875800000001,\"updateDate\":1661782798000,\"isDeleted\":0}', 13, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', '0:0:0:0:0:0:0:1', 1, 'admin', 1067246875800000001, '2023-06-14 15:37:49'); + +-- ---------------------------- +-- Table structure for sys_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menu`; +CREATE TABLE `sys_menu` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `pid` bigint(0) NULL DEFAULT NULL COMMENT '上级ID,一级菜单为0', + `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称', + `url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '菜单URL', + `permissions` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '授权(多个用逗号分隔,如:sys:user:list,sys:user:save)', + `menu_type` tinyint unsigned NULL COMMENT '类型 0:菜单 1:按钮', + `icon` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '菜单图标', + `sort` int(0) NULL DEFAULT NULL COMMENT '排序', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_pid`(`pid`) USING BTREE, + INDEX `idx_sort`(`sort`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '菜单管理' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_menu +-- ---------------------------- +INSERT INTO `sys_menu` VALUES (1067246875800000002, 0, '权限管理', NULL, NULL, 0, 'icon-safetycertificate', 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:14:57'); +INSERT INTO `sys_menu` VALUES (1067246875800000003, 1067246875800000055, '新增', NULL, 'sys:user:save,sys:dept:list,sys:role:list', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000004, 1067246875800000055, '修改', NULL, 'sys:user:update,sys:dept:list,sys:role:list', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000005, 1067246875800000055, '删除', NULL, 'sys:user:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000006, 1067246875800000055, '导出', NULL, 'sys:user:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000007, 1067246875800000002, '角色管理', 'sys/role', NULL, 0, 'icon-team', 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000008, 1067246875800000007, '查看', NULL, 'sys:role:page,sys:role:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000009, 1067246875800000007, '新增', NULL, 'sys:role:save,sys:menu:select,sys:dept:list', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000010, 1067246875800000007, '修改', NULL, 'sys:role:update,sys:menu:select,sys:dept:list', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000011, 1067246875800000007, '删除', NULL, 'sys:role:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000012, 1067246875800000002, '部门管理', 'sys/dept', NULL, 0, 'icon-apartment', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000014, 1067246875800000012, '查看', NULL, 'sys:dept:list,sys:dept:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000015, 1067246875800000012, '新增', NULL, 'sys:dept:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000016, 1067246875800000012, '修改', NULL, 'sys:dept:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000017, 1067246875800000012, '删除', NULL, 'sys:dept:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000025, 1067246875800000035, '菜单管理', 'sys/menu', NULL, 0, 'icon-unorderedlist', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000026, 1067246875800000025, '查看', NULL, 'sys:menu:list,sys:menu:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000027, 1067246875800000025, '新增', NULL, 'sys:menu:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000028, 1067246875800000025, '修改', NULL, 'sys:menu:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000029, 1067246875800000025, '删除', NULL, 'sys:menu:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000030, 1067246875800000035, '定时任务', 'job/schedule', NULL, 0, 'icon-dashboard', 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000031, 1067246875800000030, '查看', NULL, 'sys:schedule:page,sys:schedule:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000032, 1067246875800000030, '新增', NULL, 'sys:schedule:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000033, 1067246875800000030, '修改', NULL, 'sys:schedule:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000034, 1067246875800000030, '删除', NULL, 'sys:schedule:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000035, 0, '系统设置', NULL, NULL, 0, 'icon-setting', 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:05:39'); +INSERT INTO `sys_menu` VALUES (1067246875800000036, 1067246875800000030, '暂停', NULL, 'sys:schedule:pause', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000037, 1067246875800000030, '恢复', NULL, 'sys:schedule:resume', 1, NULL, 5, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000038, 1067246875800000030, '立即执行', NULL, 'sys:schedule:run', 1, NULL, 6, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000039, 1067246875800000030, '日志列表', NULL, 'sys:schedule:log', 1, NULL, 7, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000040, 1067246875800000035, '参数管理', 'sys/params', '', 0, 'icon-fileprotect', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000041, 1067246875800000035, '字典管理', 'sys/dict-type', NULL, 0, 'icon-golden-fill', 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000042, 1067246875800000041, '查看', NULL, 'sys:dict:page,sys:dict:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000043, 1067246875800000041, '新增', NULL, 'sys:dict:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000044, 1067246875800000041, '修改', NULL, 'sys:dict:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000045, 1067246875800000041, '删除', NULL, 'sys:dict:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000046, 0, '日志管理', NULL, NULL, 0, 'icon-container', 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:05:45'); +INSERT INTO `sys_menu` VALUES (1067246875800000047, 1067246875800000035, '文件上传', 'oss/oss', 'sys:oss:all', 0, 'icon-upload', 4, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000048, 1067246875800000046, '登录日志', 'sys/log-login', 'sys:log:login', 0, 'icon-filedone', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000049, 1067246875800000046, '操作日志', 'sys/log-operation', 'sys:log:operation', 0, 'icon-solution', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000050, 1067246875800000046, '异常日志', 'sys/log-error', 'sys:log:error', 0, 'icon-file-exception', 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000051, 1067246875800000053, 'SQL监控', '{{ window.SITE_CONFIG[\"apiURL\"] }}/druid/sql.html', NULL, 0, 'icon-database', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000053, 0, '系统监控', NULL, NULL, 0, 'icon-desktop', 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:05:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000055, 1067246875800000002, '用户管理', 'sys/user', NULL, 0, 'icon-user', 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000056, 1067246875800000055, '查看', NULL, 'sys:user:page,sys:user:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000057, 1067246875800000040, '新增', NULL, 'sys:params:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000058, 1067246875800000040, '导出', NULL, 'sys:params:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000059, 1067246875800000040, '查看', '', 'sys:params:page,sys:params:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000060, 1067246875800000040, '修改', NULL, 'sys:params:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1067246875800000061, 1067246875800000040, '删除', '', 'sys:params:delete', 1, '', 3, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1156748733921165314, 1067246875800000053, '接口文档', '{{ window.SITE_CONFIG[\"apiURL\"] }}/doc.html', '', 0, 'icon-file-word', 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); +INSERT INTO `sys_menu` VALUES (1667117354689961986, 0, '用户信息', 'takeout/user', NULL, 0, 'icon-desktop', 0, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:02:28'); +INSERT INTO `sys_menu` VALUES (1667117354689961987, 1667117354689961986, '查看', NULL, 'takeout:user:page,takeout:user:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354689961988, 1667117354689961986, '新增', NULL, 'takeout:user:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354689961989, 1667117354689961986, '修改', NULL, 'takeout:user:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354689961990, 1667117354689961986, '删除', NULL, 'takeout:user:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354689961991, 1667117354689961986, '导出', NULL, 'takeout:user:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354887094274, 0, '套餐管理', 'takeout/setmeal', NULL, 0, 'icon-desktop', 1, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:03:16'); +INSERT INTO `sys_menu` VALUES (1667117354887094275, 1667117354887094274, '查看', NULL, 'takeout:setmeal:page,takeout:setmeal:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354887094276, 1667117354887094274, '新增', NULL, 'takeout:setmeal:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354887094277, 1667117354887094274, '修改', NULL, 'takeout:setmeal:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354887094278, 1667117354887094274, '删除', NULL, 'takeout:setmeal:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117354887094279, 1667117354887094274, '导出', NULL, 'takeout:setmeal:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355218444289, 0, '订单管理', 'takeout/orders', NULL, 0, 'icon-desktop', 2, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:05:26'); +INSERT INTO `sys_menu` VALUES (1667117355218444290, 1667117355218444289, '查看', NULL, 'takeout:orders:page,takeout:orders:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355218444291, 1667117355218444289, '新增', NULL, 'takeout:orders:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355218444292, 1667117355218444289, '修改', NULL, 'takeout:orders:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355218444293, 1667117355218444289, '删除', NULL, 'takeout:orders:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355218444294, 1667117355218444289, '导出', NULL, 'takeout:orders:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355344273409, 0, '菜品管理', 'takeout/dish', NULL, 0, 'icon-desktop', 0, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:02:51'); +INSERT INTO `sys_menu` VALUES (1667117355344273410, 1667117355344273409, '查看', NULL, 'takeout:dish:page,takeout:dish:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355344273411, 1667117355344273409, '新增', NULL, 'takeout:dish:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355344273412, 1667117355344273409, '修改', NULL, 'takeout:dish:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355344273413, 1667117355344273409, '删除', NULL, 'takeout:dish:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355344273414, 1667117355344273409, '导出', NULL, 'takeout:dish:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355474296833, 0, '菜品及套餐分类管理', 'takeout/category', NULL, 0, 'icon-desktop', 1, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:05:11'); +INSERT INTO `sys_menu` VALUES (1667117355474296834, 1667117355474296833, '查看', NULL, 'takeout:category:page,takeout:category:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355474296835, 1667117355474296833, '新增', NULL, 'takeout:category:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355474296836, 1667117355474296833, '修改', NULL, 'takeout:category:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355474296837, 1667117355474296833, '删除', NULL, 'takeout:category:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355474296838, 1667117355474296833, '导出', NULL, 'takeout:category:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:01:47', 1067246875800000001, '2023-06-09 19:01:47'); +INSERT INTO `sys_menu` VALUES (1667117355537211394, 0, '地址管理', 'takeout/addressbook', NULL, 0, 'icon-desktop', 0, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:02:59'); +INSERT INTO `sys_menu` VALUES (1667117355537211395, 1667117355537211394, '查看', NULL, 'takeout:addressbook:page,takeout:addressbook:info', 1, NULL, 0, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355537211396, 1667117355537211394, '新增', NULL, 'takeout:addressbook:save', 1, NULL, 1, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355537211397, 1667117355537211394, '修改', NULL, 'takeout:addressbook:update', 1, NULL, 2, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355537211398, 1667117355537211394, '删除', NULL, 'takeout:addressbook:delete', 1, NULL, 3, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); +INSERT INTO `sys_menu` VALUES (1667117355537211399, 1667117355537211394, '导出', NULL, 'takeout:addressbook:export', 1, NULL, 4, 1067246875800000001, '2023-06-09 19:01:46', 1067246875800000001, '2023-06-09 19:01:46'); + +-- ---------------------------- +-- Table structure for sys_oss +-- ---------------------------- +DROP TABLE IF EXISTS `sys_oss`; +CREATE TABLE `sys_oss` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'URL地址', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '文件上传' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_params +-- ---------------------------- +DROP TABLE IF EXISTS `sys_params`; +CREATE TABLE `sys_params` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `param_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '参数编码', + `param_value` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '参数值', + `param_type` tinyint unsigned NULL COMMENT '类型 0:系统参数 1:非系统参数', + `remark` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_param_code`(`param_code`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '参数管理' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_params +-- ---------------------------- +INSERT INTO `sys_params` VALUES (1067246875800000073, 'CLOUD_STORAGE_CONFIG_KEY', '{\"type\":1,\"qiniuDomain\":\"http://test.oss.renren.io\",\"qiniuPrefix\":\"upload\",\"qiniuAccessKey\":\"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ\",\"qiniuSecretKey\":\"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV\",\"qiniuBucketName\":\"renren-oss\",\"aliyunDomain\":\"\",\"aliyunPrefix\":\"\",\"aliyunEndPoint\":\"\",\"aliyunAccessKeyId\":\"\",\"aliyunAccessKeySecret\":\"\",\"aliyunBucketName\":\"\",\"qcloudDomain\":\"\",\"qcloudPrefix\":\"\",\"qcloudSecretId\":\"\",\"qcloudSecretKey\":\"\",\"qcloudBucketName\":\"\"}', 0, '云存储配置信息', 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); + +-- ---------------------------- +-- Table structure for sys_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色名称', + `remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `dept_id` bigint(0) NULL DEFAULT NULL COMMENT '部门ID', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_dept_id`(`dept_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色管理' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_role_data_scope +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_data_scope`; +CREATE TABLE `sys_role_data_scope` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `role_id` bigint(0) NULL DEFAULT NULL COMMENT '角色ID', + `dept_id` bigint(0) NULL DEFAULT NULL COMMENT '部门ID', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_role_id`(`role_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色数据权限' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_role_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_menu`; +CREATE TABLE `sys_role_menu` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `role_id` bigint(0) NULL DEFAULT NULL COMMENT '角色ID', + `menu_id` bigint(0) NULL DEFAULT NULL COMMENT '菜单ID', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_role_id`(`role_id`) USING BTREE, + INDEX `idx_menu_id`(`menu_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色菜单关系' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_role_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_user`; +CREATE TABLE `sys_role_user` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `role_id` bigint(0) NULL DEFAULT NULL COMMENT '角色ID', + `user_id` bigint(0) NULL DEFAULT NULL COMMENT '用户ID', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_role_id`(`role_id`) USING BTREE, + INDEX `idx_user_id`(`user_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色用户关系' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for sys_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '密码', + `real_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '姓名', + `head_url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '头像', + `gender` tinyint unsigned NULL COMMENT '性别 0:男 1:女 2:保密', + `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱', + `mobile` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '手机号', + `dept_id` bigint(0) NULL DEFAULT NULL COMMENT '部门ID', + `super_admin` tinyint unsigned NULL COMMENT '超级管理员 0:否 1:是', + `status` tinyint(0) NULL DEFAULT NULL COMMENT '状态 0:停用 1:正常', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uk_username`(`username`) USING BTREE, + INDEX `idx_create_date`(`create_date`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +INSERT INTO `sys_user` VALUES (1067246875800000001, 'admin', '$2a$10$012Kx2ba5jzqr9gLlG4MX.bnQJTD9UWqF57XDo2N3.fPtLne02u/m', '管理员', NULL, 0, 'root@renren.io', '13612345678', NULL, 1, 1, 1067246875800000001, '2023-06-09 19:00:49', 1067246875800000001, '2023-06-09 19:00:49'); + +-- ---------------------------- +-- Table structure for sys_user_token +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_token`; +CREATE TABLE `sys_user_token` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `user_id` bigint(0) NOT NULL COMMENT '用户id', + `token` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户token', + `expire_date` datetime(0) NULL DEFAULT NULL COMMENT '过期时间', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `user_id`(`user_id`) USING BTREE, + UNIQUE INDEX `token`(`token`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统用户Token' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user_token +-- ---------------------------- +INSERT INTO `sys_user_token` VALUES (1667124900934565889, 1067246875800000001, '1904c2b953248bb8ab8f62bbc90d00e4', '2023-06-15 03:37:06', '2023-06-14 15:37:06', '2023-06-09 19:02:05'); + +-- ---------------------------- +-- Table structure for tb_token +-- ---------------------------- +DROP TABLE IF EXISTS `tb_token`; +CREATE TABLE `tb_token` ( + `id` bigint(0) NOT NULL COMMENT 'id', + `user_id` bigint(0) NOT NULL COMMENT '用户ID', + `token` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'token', + `expire_date` datetime(0) NULL DEFAULT NULL COMMENT '过期时间', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `user_id`(`user_id`) USING BTREE, + UNIQUE INDEX `token`(`token`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户Token' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of tb_token +-- ---------------------------- +INSERT INTO `tb_token` VALUES (1562819873267068930, 1562819873229320194, 'decff2481e9d41b3a1402d54b6a5d6ab', '2022-08-26 11:11:08', '2022-08-25 23:11:08'); +INSERT INTO `tb_token` VALUES (1562837457970499586, 1534405913534889985, 'd58caef22a7f4947a72dc18ee18497ae', '2022-08-28 08:29:40', '2022-08-27 20:29:40'); + +-- ---------------------------- +-- Table structure for user +-- ---------------------------- +DROP TABLE IF EXISTS `user`; +CREATE TABLE `user` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT 'id', + `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '姓名', + `phone` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '手机号', + `gender` tinyint(0) NULL DEFAULT NULL COMMENT '性别 0:男 1:女 2:保密', + `id_number` varchar(18) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '身份证号', + `avatar_url` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '头像', + `status` tinyint(0) NULL DEFAULT 1 COMMENT '状态 0:禁用,1:正常', + `openid` varchar(90) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '微信openid', + `nick_name` varchar(150) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '微信昵称', + `creator` bigint(0) NULL DEFAULT NULL COMMENT '创建者', + `create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `updater` bigint(0) NULL DEFAULT NULL COMMENT '更新者', + `update_date` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户信息' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of user +-- ---------------------------- +INSERT INTO `user` VALUES (1668247645219012609, NULL, '1029606625@qq.com', NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL); + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9fe62d1 --- /dev/null +++ b/pom.xml @@ -0,0 +1,212 @@ + + 4.0.0 + io.renren + renren-security + 5.2.0 + pom + + renren-security + 人人权限系统 + https://www.renren.io + + + org.springframework.boot + spring-boot-starter-parent + 2.7.5 + + + + renren-common + renren-dynamic-datasource + renren-admin + renren-api + renren-generator + + + + UTF-8 + UTF-8 + 1.8 + 4.2.2 + 1.2.13 + 3.5.2 + 4.0 + 11.2.0.3 + 8.1.2.79 + 3.12.0 + 1.4 + 2.11.0 + 1.15 + 20.0 + 2.10.14 + 5.7.22 + 2.9.0 + 1.15.3 + 2.0.9 + 1.18.24 + 1.1.1 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework + spring-context-support + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-configuration-processor + true + + + redis.clients + jedis + ${jedis.version} + + + + com.mysql + mysql-connector-j + + + + com.oracle + ojdbc6 + ${oracle.version} + + + + com.microsoft.sqlserver + sqljdbc4 + ${sqlserver.version} + + + + org.postgresql + postgresql + + + + com.dameng + DmJdbcDriver18 + ${dameng.version} + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatisplus.version} + + + com.baomidou + mybatis-plus-generator + + + + + org.apache.commons + commons-lang3 + ${commons.lang.version} + + + commons-fileupload + commons-fileupload + ${commons.fileupload.version} + + + commons-io + commons-io + ${commons.io.version} + + + commons-codec + commons-codec + ${commons.codec.version} + + + com.google.guava + guava + ${guava.version} + + + joda-time + joda-time + ${joda.time.version} + + + com.google.code.gson + gson + ${gson.version} + + + cn.hutool + hutool-all + ${hutool.version} + + + org.jsoup + jsoup + ${jsoup.version} + + + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public/ + + true + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public/ + + true + + + false + + + + \ No newline at end of file diff --git a/renren-admin/Dockerfile b/renren-admin/Dockerfile new file mode 100644 index 0000000..9db81f6 --- /dev/null +++ b/renren-admin/Dockerfile @@ -0,0 +1,7 @@ +FROM java:8 +EXPOSE 8080 + +VOLUME /tmp +ADD renren-admin.jar /app.jar +RUN bash -c 'touch /app.jar' +ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/renren-admin/db/dm8.sql b/renren-admin/db/dm8.sql new file mode 100644 index 0000000..682c2ff --- /dev/null +++ b/renren-admin/db/dm8.sql @@ -0,0 +1,674 @@ +CREATE TABLE sys_user ( + id bigint NOT NULL, + username varchar(50) NOT NULL, + password varchar(100), + real_name varchar(50), + head_url varchar(200), + gender int, + email varchar(100), + mobile varchar(100), + dept_id bigint, + super_admin int, + status int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); + +CREATE UNIQUE INDEX uk_sys_user_username on sys_user(username); +CREATE INDEX idx_sys_user_create_date on sys_user(create_date); + +COMMENT ON TABLE sys_user IS '用户管理'; +COMMENT ON COLUMN sys_user.id IS 'id'; +COMMENT ON COLUMN sys_user.username IS '用户名'; +COMMENT ON COLUMN sys_user.password IS '密码'; +COMMENT ON COLUMN sys_user.real_name IS '姓名'; +COMMENT ON COLUMN sys_user.head_url IS '头像'; +COMMENT ON COLUMN sys_user.gender IS '性别 0:男 1:女 2:保密'; +COMMENT ON COLUMN sys_user.email IS '邮箱'; +COMMENT ON COLUMN sys_user.mobile IS '手机号'; +COMMENT ON COLUMN sys_user.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_user.super_admin IS '超级管理员 0:否 1:是'; +COMMENT ON COLUMN sys_user.status IS '状态 0:停用 1:正常'; +COMMENT ON COLUMN sys_user.creator IS '创建者'; +COMMENT ON COLUMN sys_user.create_date IS '创建时间'; +COMMENT ON COLUMN sys_user.updater IS '更新者'; +COMMENT ON COLUMN sys_user.update_date IS '更新时间'; + + +CREATE TABLE sys_dept ( + id bigint NOT NULL, + pid bigint, + pids varchar(500), + name varchar(50), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE INDEX idx_sys_dept_pid on sys_dept(pid); +CREATE INDEX idx_sys_dept_idx_sort on sys_dept(sort); + +COMMENT ON TABLE sys_dept IS '部门管理'; +COMMENT ON COLUMN sys_dept.id IS 'id'; +COMMENT ON COLUMN sys_dept.pid IS '上级ID'; +COMMENT ON COLUMN sys_dept.pids IS '所有上级ID,用逗号分开'; +COMMENT ON COLUMN sys_dept.name IS '部门名称'; +COMMENT ON COLUMN sys_dept.sort IS '排序'; +COMMENT ON COLUMN sys_dept.creator IS '创建者'; +COMMENT ON COLUMN sys_dept.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dept.updater IS '更新者'; +COMMENT ON COLUMN sys_dept.update_date IS '更新时间'; + + +create table sys_role +( + id bigint NOT NULL, + name varchar(50), + remark varchar(100), + dept_id bigint, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_role_dept_id on sys_role(dept_id); + +COMMENT ON TABLE sys_role IS '角色管理'; +COMMENT ON COLUMN sys_role.id IS 'id'; +COMMENT ON COLUMN sys_role.name IS '角色名称'; +COMMENT ON COLUMN sys_role.remark IS '备注'; +COMMENT ON COLUMN sys_role.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_role.creator IS '创建者'; +COMMENT ON COLUMN sys_role.create_date IS '创建时间'; +COMMENT ON COLUMN sys_role.updater IS '更新者'; +COMMENT ON COLUMN sys_role.update_date IS '更新时间'; + + +create table sys_menu +( + id bigint NOT NULL, + pid bigint, + name varchar(200), + url varchar(200), + permissions varchar(500), + menu_type int, + icon varchar(50), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_menu_pid on sys_menu(pid); +CREATE INDEX idx_sys_menu_sort on sys_menu(sort); + +COMMENT ON TABLE sys_menu IS '菜单管理'; +COMMENT ON COLUMN sys_menu.id IS 'id'; +COMMENT ON COLUMN sys_menu.pid IS '上级ID,一级菜单为0'; +COMMENT ON COLUMN sys_menu.name IS '名称'; +COMMENT ON COLUMN sys_menu.url IS '菜单URL'; +COMMENT ON COLUMN sys_menu.permissions IS '授权(多个用逗号分隔,如:sys:user:list,sys:user:save)'; +COMMENT ON COLUMN sys_menu.menu_type IS '类型 0:菜单 1:按钮'; +COMMENT ON COLUMN sys_menu.icon IS '菜单图标'; +COMMENT ON COLUMN sys_menu.sort IS '排序'; +COMMENT ON COLUMN sys_menu.creator IS '创建者'; +COMMENT ON COLUMN sys_menu.create_date IS '创建时间'; +COMMENT ON COLUMN sys_menu.updater IS '更新者'; +COMMENT ON COLUMN sys_menu.update_date IS '更新时间'; + + +create table sys_role_user +( + id bigint NOT NULL, + role_id bigint, + user_id bigint, + creator bigint, + create_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_role_user_role_id on sys_role_user(role_id); +CREATE INDEX idx_sys_role_user_user_id on sys_role_user(user_id); + +COMMENT ON TABLE sys_role_user IS '角色用户关系'; +COMMENT ON COLUMN sys_role_user.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_user.user_id IS '用户ID'; +COMMENT ON COLUMN sys_role_user.creator IS '创建者'; +COMMENT ON COLUMN sys_role_user.create_date IS '创建时间'; + + +create table sys_role_menu +( + id bigint NOT NULL, + role_id bigint, + menu_id bigint, + creator bigint, + create_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_role_menu_role_id on sys_role_menu(role_id); +CREATE INDEX idx_sys_role_menu_menu_id on sys_role_menu(menu_id); + +COMMENT ON TABLE sys_role_menu IS '角色菜单关系'; +COMMENT ON COLUMN sys_role_menu.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_menu.menu_id IS '菜单ID'; +COMMENT ON COLUMN sys_role_menu.creator IS '创建者'; +COMMENT ON COLUMN sys_role_menu.create_date IS '创建时间'; + + +create table sys_role_data_scope +( + id bigint NOT NULL, + role_id bigint, + dept_id bigint, + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_data_scope_role_id on sys_role_data_scope(role_id); + +COMMENT ON TABLE sys_role_data_scope IS '角色数据权限'; +COMMENT ON COLUMN sys_role_data_scope.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_data_scope.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_role_data_scope.creator IS '创建者'; +COMMENT ON COLUMN sys_role_data_scope.create_date IS '创建时间'; + + +create table sys_params +( + id bigint NOT NULL, + param_code varchar(32), + param_value varchar(2000), + param_type int DEFAULT 1 NOT NULL, + remark varchar(200), + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_params_param_code on sys_params(param_code); +CREATE INDEX idx_sys_params_create_date on sys_params(create_date); + +COMMENT ON TABLE sys_params IS '参数管理'; +COMMENT ON COLUMN sys_params.param_code IS '参数编码'; +COMMENT ON COLUMN sys_params.param_value IS '参数值'; +COMMENT ON COLUMN sys_params.param_type IS '类型 0:系统参数 1:非系统参数'; +COMMENT ON COLUMN sys_params.remark IS '备注'; +COMMENT ON COLUMN sys_params.creator IS '创建者'; +COMMENT ON COLUMN sys_params.create_date IS '创建时间'; +COMMENT ON COLUMN sys_params.updater IS '更新者'; +COMMENT ON COLUMN sys_params.update_date IS '更新时间'; + + +create table sys_dict_type +( + id bigint NOT NULL, + dict_type varchar(100), + dict_name varchar(255), + remark varchar(255), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_dict_type_dict_type on sys_dict_type(dict_type); + +COMMENT ON TABLE sys_dict_type IS '字典类型'; +COMMENT ON COLUMN sys_dict_type.id IS 'id'; +COMMENT ON COLUMN sys_dict_type.dict_type IS '字典类型'; +COMMENT ON COLUMN sys_dict_type.dict_name IS '字典名称'; +COMMENT ON COLUMN sys_dict_type.remark IS '备注'; +COMMENT ON COLUMN sys_dict_type.sort IS '排序'; +COMMENT ON COLUMN sys_dict_type.creator IS '创建者'; +COMMENT ON COLUMN sys_dict_type.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dict_type.updater IS '更新者'; +COMMENT ON COLUMN sys_dict_type.update_date IS '更新时间'; + +create table sys_dict_data +( + id bigint NOT NULL, + dict_type_id bigint NOT NULL, + dict_label varchar(255), + dict_value varchar(255), + remark varchar(255), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE INDEX idx_sys_dict_data_sort on sys_dict_data(sort); +CREATE UNIQUE INDEX uk_dict_type_value on sys_dict_data(dict_type_id, dict_value); + +COMMENT ON TABLE sys_dict_data IS '字典数据'; +COMMENT ON COLUMN sys_dict_data.id IS 'id'; +COMMENT ON COLUMN sys_dict_data.dict_type_id IS '字典类型ID'; +COMMENT ON COLUMN sys_dict_data.dict_label IS '字典标签'; +COMMENT ON COLUMN sys_dict_data.dict_value IS '字典值'; +COMMENT ON COLUMN sys_dict_data.remark IS '备注'; +COMMENT ON COLUMN sys_dict_data.sort IS '排序'; +COMMENT ON COLUMN sys_dict_data.creator IS '创建者'; +COMMENT ON COLUMN sys_dict_data.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dict_data.updater IS '更新者'; +COMMENT ON COLUMN sys_dict_data.update_date IS '更新时间'; + + +create table sys_log_login +( + id bigint NOT NULL, + operation int, + status int, + user_agent varchar(500), + ip varchar(32), + creator_name varchar(50), + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_login_status on sys_log_login(status); +CREATE INDEX idx_login_create_date on sys_log_login(create_date); + +COMMENT ON TABLE sys_log_login IS '登录日志'; +COMMENT ON COLUMN sys_log_login.id IS 'id'; +COMMENT ON COLUMN sys_log_login.operation IS '用户操作 0:用户登录 1:用户退出'; +COMMENT ON COLUMN sys_log_login.status IS '状态 0:失败 1:成功 2:账号已锁定'; +COMMENT ON COLUMN sys_log_login.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_login.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_login.creator_name IS '用户名'; +COMMENT ON COLUMN sys_log_login.creator IS '创建者'; +COMMENT ON COLUMN sys_log_login.create_date IS '创建时间'; + + +create table sys_log_operation +( + id bigint NOT NULL, + operation varchar(50), + request_uri varchar(200), + request_method varchar(20), + request_params text, + request_time int, + user_agent varchar(500), + ip varchar(32), + status int, + creator_name varchar(50), + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_operation_create_date on sys_log_operation(create_date); + +COMMENT ON TABLE sys_log_operation IS '操作日志'; +COMMENT ON COLUMN sys_log_operation.id IS 'id'; +COMMENT ON COLUMN sys_log_operation.operation IS '用户操作'; +COMMENT ON COLUMN sys_log_operation.request_uri IS '请求URI'; +COMMENT ON COLUMN sys_log_operation.request_method IS '请求方式'; +COMMENT ON COLUMN sys_log_operation.request_params IS '请求参数'; +COMMENT ON COLUMN sys_log_operation.request_time IS '请求时长(毫秒)'; +COMMENT ON COLUMN sys_log_operation.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_operation.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_operation.status IS '状态 0:失败 1:成功'; +COMMENT ON COLUMN sys_log_operation.creator_name IS '用户名'; +COMMENT ON COLUMN sys_log_operation.creator IS '创建者'; +COMMENT ON COLUMN sys_log_operation.create_date IS '创建时间'; + + +create table sys_log_error +( + id bigint NOT NULL, + request_uri varchar(200), + request_method varchar(20), + request_params text, + user_agent varchar(500), + ip varchar(32), + error_info text, + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_error_create_date on sys_log_error(create_date); + +COMMENT ON TABLE sys_log_error IS '异常日志'; +COMMENT ON COLUMN sys_log_error.id IS 'id'; +COMMENT ON COLUMN sys_log_error.request_uri IS '请求URI'; +COMMENT ON COLUMN sys_log_error.request_method IS '请求方式'; +COMMENT ON COLUMN sys_log_error.request_params IS '请求参数'; +COMMENT ON COLUMN sys_log_error.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_error.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_error.error_info IS '异常信息'; +COMMENT ON COLUMN sys_log_error.creator IS '创建者'; +COMMENT ON COLUMN sys_log_error.create_date IS '创建时间'; + + + +CREATE TABLE sys_oss ( + id bigint NOT NULL, + url varchar(200), + creator bigint, + create_date datetime, + PRIMARY KEY (id) +); +CREATE INDEX idx_sys_oss_create_date on sys_oss(create_date); + +COMMENT ON TABLE sys_oss IS '文件上传'; +COMMENT ON COLUMN sys_oss.id IS 'id'; +COMMENT ON COLUMN sys_oss.url IS 'URL地址'; +COMMENT ON COLUMN sys_oss.creator IS '创建者'; +COMMENT ON COLUMN sys_oss.create_date IS '创建时间'; + + +CREATE TABLE schedule_job ( + id bigint NOT NULL, + bean_name varchar(200), + params varchar(2000), + cron_expression varchar(100), + status int, + remark varchar(255), + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + PRIMARY KEY (id) +); + +CREATE INDEX idx_schedule_job_create_date on schedule_job(create_date); + +COMMENT ON TABLE schedule_job IS '定时任务'; +COMMENT ON COLUMN schedule_job.id IS 'id'; +COMMENT ON COLUMN schedule_job.bean_name IS 'spring bean名称'; +COMMENT ON COLUMN schedule_job.params IS '参数'; +COMMENT ON COLUMN schedule_job.cron_expression IS 'cron表达式'; +COMMENT ON COLUMN schedule_job.status IS '任务状态 0:暂停 1:正常'; +COMMENT ON COLUMN schedule_job.remark IS '备注'; +COMMENT ON COLUMN schedule_job.creator IS '创建者'; +COMMENT ON COLUMN schedule_job.create_date IS '创建时间'; +COMMENT ON COLUMN schedule_job.updater IS '更新者'; +COMMENT ON COLUMN schedule_job.update_date IS '更新时间'; + + +CREATE TABLE schedule_job_log ( + id bigint NOT NULL, + job_id bigint NOT NULL, + bean_name varchar(200), + params varchar(2000), + status int, + error varchar(2000), + times int, + create_date datetime, + PRIMARY KEY (id) +); + +CREATE INDEX idx_job_log_job_id on schedule_job_log(job_id); +CREATE INDEX idx_job_log_create_date on schedule_job_log(create_date); + +COMMENT ON TABLE schedule_job_log IS '定时任务日志'; +COMMENT ON COLUMN schedule_job_log.id IS 'id'; +COMMENT ON COLUMN schedule_job_log.bean_name IS 'spring bean名称'; +COMMENT ON COLUMN schedule_job_log.params IS '参数'; +COMMENT ON COLUMN schedule_job_log.status IS '任务状态 0:失败 1:成功'; +COMMENT ON COLUMN schedule_job_log.error IS '失败信息'; +COMMENT ON COLUMN schedule_job_log.times IS '耗时(单位:毫秒)'; +COMMENT ON COLUMN schedule_job.create_date IS '创建时间'; + + +CREATE TABLE sys_user_token ( + id bigint NOT NULL, + user_id bigint, + token varchar(100), + expire_date datetime, + update_date datetime, + create_date datetime, + PRIMARY KEY (id) +); + +CREATE UNIQUE INDEX uk_sys_user_token_user_id on sys_user_token(user_id); +CREATE UNIQUE INDEX uk_sys_user_token on sys_user_token(token); + +COMMENT ON TABLE sys_user_token IS '系统用户Token'; +COMMENT ON COLUMN sys_user_token.id IS 'id'; +COMMENT ON COLUMN sys_user_token.user_id IS '用户id'; +COMMENT ON COLUMN sys_user_token.token IS '用户token'; +COMMENT ON COLUMN sys_user_token.expire_date IS '过期时间'; +COMMENT ON COLUMN sys_user_token.update_date IS '更新时间'; +COMMENT ON COLUMN sys_user_token.create_date IS '创建时间'; + + + +-- 初始数据 +INSERT INTO sys_user(id, username, password, real_name, gender, email, mobile, status, dept_id, super_admin, creator, create_date, updater, update_date) VALUES (1067246875800000001, 'admin', '$2a$10$012Kx2ba5jzqr9gLlG4MX.bnQJTD9UWqF57XDo2N3.fPtLne02u/m', '管理员', 0, 'root@renren.io', '13612345678', 1, null, 1, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000002, 0, '权限管理', NULL, NULL, 0, 'icon-safetycertificate', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000003, 1067246875800000055, '新增', NULL, 'sys:user:save,sys:dept:list,sys:role:list', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000004, 1067246875800000055, '修改', NULL, 'sys:user:update,sys:dept:list,sys:role:list', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000005, 1067246875800000055, '删除', NULL, 'sys:user:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000006, 1067246875800000055, '导出', NULL, 'sys:user:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000007, 1067246875800000002, '角色管理', 'sys/role', NULL, 0, 'icon-team', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000008, 1067246875800000007, '查看', NULL, 'sys:role:page,sys:role:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000009, 1067246875800000007, '新增', NULL, 'sys:role:save,sys:menu:select,sys:dept:list', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000010, 1067246875800000007, '修改', NULL, 'sys:role:update,sys:menu:select,sys:dept:list', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000011, 1067246875800000007, '删除', NULL, 'sys:role:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000012, 1067246875800000002, '部门管理', 'sys/dept', NULL, 0, 'icon-apartment', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000014, 1067246875800000012, '查看', NULL, 'sys:dept:list,sys:dept:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000015, 1067246875800000012, '新增', NULL, 'sys:dept:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000016, 1067246875800000012, '修改', NULL, 'sys:dept:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000017, 1067246875800000012, '删除', NULL, 'sys:dept:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000025, 1067246875800000035, '菜单管理', 'sys/menu', NULL, 0, 'icon-unorderedlist', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000026, 1067246875800000025, '查看', NULL, 'sys:menu:list,sys:menu:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000027, 1067246875800000025, '新增', NULL, 'sys:menu:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000028, 1067246875800000025, '修改', NULL, 'sys:menu:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000029, 1067246875800000025, '删除', NULL, 'sys:menu:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000030, 1067246875800000035, '定时任务', 'job/schedule', NULL, 0, 'icon-dashboard', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000031, 1067246875800000030, '查看', NULL, 'sys:schedule:page,sys:schedule:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000032, 1067246875800000030, '新增', NULL, 'sys:schedule:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000033, 1067246875800000030, '修改', NULL, 'sys:schedule:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000034, 1067246875800000030, '删除', NULL, 'sys:schedule:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000035, 0, '系统设置', NULL, NULL, 0, 'icon-setting', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000036, 1067246875800000030, '暂停', NULL, 'sys:schedule:pause', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000037, 1067246875800000030, '恢复', NULL, 'sys:schedule:resume', 1, NULL, 5, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000038, 1067246875800000030, '立即执行', NULL, 'sys:schedule:run', 1, NULL, 6, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000039, 1067246875800000030, '日志列表', NULL, 'sys:schedule:log', 1, NULL, 7, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000040, 1067246875800000035, '参数管理', 'sys/params', '', 0, 'icon-fileprotect', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000041, 1067246875800000035, '字典管理', 'sys/dict-type', NULL, 0, 'icon-golden-fill', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000042, 1067246875800000041, '查看', NULL, 'sys:dict:page,sys:dict:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000043, 1067246875800000041, '新增', NULL, 'sys:dict:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000044, 1067246875800000041, '修改', NULL, 'sys:dict:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000045, 1067246875800000041, '删除', NULL, 'sys:dict:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000046, 0, '日志管理', NULL, NULL, 0, 'icon-container', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000047, 1067246875800000035, '文件上传', 'oss/oss', 'sys:oss:all', 0, 'icon-upload', 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000048, 1067246875800000046, '登录日志', 'sys/log-login', 'sys:log:login', 0, 'icon-filedone', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000049, 1067246875800000046, '操作日志', 'sys/log-operation', 'sys:log:operation', 0, 'icon-solution', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000050, 1067246875800000046, '异常日志', 'sys/log-error', 'sys:log:error', 0, 'icon-file-exception', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000051, 1067246875800000053, 'SQL监控', '{{ window.SITE_CONFIG["apiURL"] }}/druid/sql.html', NULL, 0, 'icon-database', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000053, 0, '系统监控', NULL, NULL, 0, 'icon-desktop', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000055, 1067246875800000002, '用户管理', 'sys/user', NULL, 0, 'icon-user', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000056, 1067246875800000055, '查看', NULL, 'sys:user:page,sys:user:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000057, 1067246875800000040, '新增', NULL, 'sys:params:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000058, 1067246875800000040, '导出', NULL, 'sys:params:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000059, 1067246875800000040, '查看', '', 'sys:params:page,sys:params:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000060, 1067246875800000040, '修改', NULL, 'sys:params:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000061, 1067246875800000040, '删除', '', 'sys:params:delete', 1, '', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1156748733921165314, 1067246875800000053, '接口文档', '{{ window.SITE_CONFIG["apiURL"] }}/doc.html', '', 0, 'icon-file-word', 1, 1067246875800000001, now(), 1067246875800000001, now()); + + +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000062, 1067246875800000063, '1067246875800000066,1067246875800000063', '技术部', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000063, 1067246875800000066, '1067246875800000066', '长沙分公司', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000064, 1067246875800000066, '1067246875800000066', '上海分公司', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000065, 1067246875800000064, '1067246875800000066,1067246875800000064', '市场部', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000066, 0, '0', '人人开源集团', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000067, 1067246875800000064, '1067246875800000066,1067246875800000064', '销售部', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000068, 1067246875800000063, '1067246875800000066,1067246875800000063', '产品部', 1, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1160061077912858625, 'gender', '性别', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061112075464705, 1160061077912858625, '男', '0', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061146967879681, 1160061077912858625, '女', '1', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061190127267841, 1160061077912858625, '保密', '2', '', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1225813644059140097, 'notice_type', '站内通知-类型', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814069634195457, 1225813644059140097, '公告', '0', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814107559092225, 1225813644059140097, '会议', '1', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814271879340034, 1225813644059140097, '其他', '2', '', 2, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_params(id, param_code, param_value, param_type, remark, creator, create_date, updater, update_date) VALUES (1067246875800000073, 'CLOUD_STORAGE_CONFIG_KEY', '{"type":1,"qiniuDomain":"http://test.oss.renren.io","qiniuPrefix":"upload","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","qiniuBucketName":"renren-oss","aliyunDomain":"","aliyunPrefix":"","aliyunEndPoint":"","aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qcloudBucketName":""}', '0', '云存储配置信息', 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO schedule_job (id, bean_name, params, cron_expression, status, remark, creator, create_date, updater, update_date) VALUES (1067246875800000076, 'testTask', 'renren', '0 0/30 * * * ?', 0, '有参测试,多个参数使用json', 1067246875800000001, now(), 1067246875800000001, now()); + + + + +-- quartz自带表结构 +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +create table QRTZ_JOB_DETAILS ( + sched_name varchar(120) not null, + job_name varchar(200) not null, + job_group varchar(200) not null, + description varchar(250) null, + job_class_name varchar(250) not null, + is_durable varchar(1) not null, + is_nonconcurrent varchar(1) not null, + is_update_data varchar(1) not null, + requests_recovery varchar(1) not null, + job_data blob null, + primary key (sched_name, job_name, job_group) +); + +create table QRTZ_TRIGGERS ( + sched_name varchar(120) not null, + trigger_name varchar(200) not null, + trigger_group varchar(200) not null, + job_name varchar(200) not null, + job_group varchar(200) not null, + description varchar(250) null, + next_fire_time bigint null, + prev_fire_time bigint null, + priority int null, + trigger_state varchar(16) not null, + trigger_type varchar(8) not null, + start_time bigint not null, + end_time bigint null, + calendar_name varchar(200) null, + misfire_instr int null, + job_data blob null, + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, job_name, job_group) + references QRTZ_JOB_DETAILS(sched_name, job_name, job_group) +); + +create table QRTZ_SIMPLE_TRIGGERS ( + sched_name varchar(120) not null, + trigger_name varchar(200) not null, + trigger_group varchar(200) not null, + repeat_count bigint not null, + repeat_interval bigint not null, + times_triggered bigint not null, + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) + references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +); + +create table QRTZ_CRON_TRIGGERS ( + sched_name varchar(120) not null, + trigger_name varchar(200) not null, + trigger_group varchar(200) not null, + cron_expression varchar(200) not null, + time_zone_id varchar(80), + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) + references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +); + +create table QRTZ_BLOB_TRIGGERS ( + sched_name varchar(120) not null, + trigger_name varchar(200) not null, + trigger_group varchar(200) not null, + blob_data blob null, + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) + references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +); + +create table QRTZ_CALENDARS ( + sched_name varchar(120) not null, + calendar_name varchar(200) not null, + calendar blob not null, + primary key (sched_name, calendar_name) +); + +create table QRTZ_PAUSED_TRIGGER_GRPS ( + sched_name varchar(120) not null, + trigger_group varchar(200) not null, + primary key (sched_name, trigger_group) +); + +create table QRTZ_FIRED_TRIGGERS ( + sched_name varchar(120) not null, + entry_id varchar(95) not null, + trigger_name varchar(200) not null, + trigger_group varchar(200) not null, + instance_name varchar(200) not null, + fired_time bigint not null, + sched_time bigint not null, + priority int not null, + state varchar(16) not null, + job_name varchar(200) null, + job_group varchar(200) null, + is_nonconcurrent varchar(1) null, + requests_recovery varchar(1) null, + primary key (sched_name, entry_id) +); + +create table QRTZ_SCHEDULER_STATE ( + sched_name varchar(120) not null, + instance_name varchar(200) not null, + last_checkin_time bigint not null, + checkin_interval bigint not null, + primary key (sched_name, instance_name) +); + +create table QRTZ_LOCKS ( + sched_name varchar(120) not null, + lock_name varchar(40) not null, + primary key (sched_name, lock_name) +); + +create table QRTZ_SIMPROP_TRIGGERS ( + sched_name varchar(120) not null, + trigger_name varchar(200) not null, + trigger_group varchar(200) not null, + str_prop_1 varchar(512) null, + str_prop_2 varchar(512) null, + str_prop_3 varchar(512) null, + int_prop_1 int null, + int_prop_2 int null, + long_prop_1 bigint null, + long_prop_2 bigint null, + dec_prop_1 numeric(13,4) null, + dec_prop_2 numeric(13,4) null, + bool_prop_1 varchar(1) null, + bool_prop_2 varchar(1) null, + primary key (sched_name, trigger_name, trigger_group), + foreign key (sched_name, trigger_name, trigger_group) + references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group) +); \ No newline at end of file diff --git a/renren-admin/db/mysql.sql b/renren-admin/db/mysql.sql new file mode 100644 index 0000000..c700c7e --- /dev/null +++ b/renren-admin/db/mysql.sql @@ -0,0 +1,504 @@ +-- 系统用户 +CREATE TABLE sys_user ( + id bigint NOT NULL COMMENT 'id', + username varchar(50) NOT NULL COMMENT '用户名', + password varchar(100) COMMENT '密码', + real_name varchar(50) COMMENT '姓名', + head_url varchar(200) COMMENT '头像', + gender tinyint unsigned COMMENT '性别 0:男 1:女 2:保密', + email varchar(100) COMMENT '邮箱', + mobile varchar(100) COMMENT '手机号', + dept_id bigint COMMENT '部门ID', + super_admin tinyint unsigned COMMENT '超级管理员 0:否 1:是', + status tinyint COMMENT '状态 0:停用 1:正常', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + primary key (id), + unique key uk_username (username), + key idx_create_date (create_date) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户'; + +-- 部门 +CREATE TABLE sys_dept ( + id bigint NOT NULL COMMENT 'id', + pid bigint COMMENT '上级ID', + pids varchar(500) COMMENT '所有上级ID,用逗号分开', + name varchar(50) COMMENT '部门名称', + sort int unsigned COMMENT '排序', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + primary key (id), + key idx_pid (pid), + key idx_sort (sort) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='部门管理'; + +-- 角色管理 +create table sys_role +( + id bigint NOT NULL COMMENT 'id', + name varchar(50) COMMENT '角色名称', + remark varchar(100) COMMENT '备注', + dept_id bigint COMMENT '部门ID', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + primary key (id), + key idx_dept_id (dept_id) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='角色管理'; + +-- 菜单管理 +create table sys_menu +( + id bigint NOT NULL COMMENT 'id', + pid bigint COMMENT '上级ID,一级菜单为0', + name varchar(200) COMMENT '名称', + url varchar(200) COMMENT '菜单URL', + permissions varchar(500) COMMENT '授权(多个用逗号分隔,如:sys:user:list,sys:user:save)', + menu_type tinyint unsigned COMMENT '类型 0:菜单 1:按钮', + icon varchar(50) COMMENT '菜单图标', + sort int COMMENT '排序', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + primary key (id), + key idx_pid (pid), + key idx_sort (sort) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='菜单管理'; + +-- 角色用户关系 +create table sys_role_user +( + id bigint NOT NULL COMMENT 'id', + role_id bigint COMMENT '角色ID', + user_id bigint COMMENT '用户ID', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + primary key (id), + key idx_role_id (role_id), + key idx_user_id (user_id) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='角色用户关系'; + +-- 角色菜单关系 +create table sys_role_menu +( + id bigint NOT NULL COMMENT 'id', + role_id bigint COMMENT '角色ID', + menu_id bigint COMMENT '菜单ID', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + primary key (id), + key idx_role_id (role_id), + key idx_menu_id (menu_id) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='角色菜单关系'; + +-- 角色数据权限 +create table sys_role_data_scope +( + id bigint NOT NULL COMMENT 'id', + role_id bigint COMMENT '角色ID', + dept_id bigint COMMENT '部门ID', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + primary key (id), + key idx_role_id (role_id) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='角色数据权限'; + +-- 参数管理 +create table sys_params +( + id bigint NOT NULL COMMENT 'id', + param_code varchar(32) COMMENT '参数编码', + param_value varchar(2000) COMMENT '参数值', + param_type tinyint unsigned default 1 COMMENT '类型 0:系统参数 1:非系统参数', + remark varchar(200) COMMENT '备注', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + primary key (id), + unique key uk_param_code (param_code), + key idx_create_date (create_date) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='参数管理'; + +-- 字典类型 +create table sys_dict_type +( + id bigint NOT NULL COMMENT 'id', + dict_type varchar(100) NOT NULL COMMENT '字典类型', + dict_name varchar(255) NOT NULL COMMENT '字典名称', + remark varchar(255) COMMENT '备注', + sort int unsigned COMMENT '排序', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + primary key (id), + UNIQUE KEY(dict_type) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='字典类型'; + +-- 字典数据 +create table sys_dict_data +( + id bigint NOT NULL COMMENT 'id', + dict_type_id bigint NOT NULL COMMENT '字典类型ID', + dict_label varchar(255) NOT NULL COMMENT '字典标签', + dict_value varchar(255) COMMENT '字典值', + remark varchar(255) COMMENT '备注', + sort int unsigned COMMENT '排序', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + primary key (id), + unique key uk_dict_type_value (dict_type_id, dict_value), + key idx_sort (sort) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='字典数据'; + +-- 登录日志 +create table sys_log_login +( + id bigint NOT NULL COMMENT 'id', + operation tinyint unsigned COMMENT '用户操作 0:用户登录 1:用户退出', + status tinyint unsigned NOT NULL COMMENT '状态 0:失败 1:成功 2:账号已锁定', + user_agent varchar(500) COMMENT '用户代理', + ip varchar(32) COMMENT '操作IP', + creator_name varchar(50) COMMENT '用户名', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + primary key (id), + key idx_status (status), + key idx_create_date (create_date) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='登录日志'; + +-- 操作日志 +create table sys_log_operation +( + id bigint NOT NULL COMMENT 'id', + operation varchar(50) COMMENT '用户操作', + request_uri varchar(200) COMMENT '请求URI', + request_method varchar(20) COMMENT '请求方式', + request_params text COMMENT '请求参数', + request_time int unsigned NOT NULL COMMENT '请求时长(毫秒)', + user_agent varchar(500) COMMENT '用户代理', + ip varchar(32) COMMENT '操作IP', + status tinyint unsigned NOT NULL COMMENT '状态 0:失败 1:成功', + creator_name varchar(50) COMMENT '用户名', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + primary key (id), + key idx_create_date (create_date) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='操作日志'; + +-- 异常日志 +create table sys_log_error +( + id bigint NOT NULL COMMENT 'id', + request_uri varchar(200) COMMENT '请求URI', + request_method varchar(20) COMMENT '请求方式', + request_params text COMMENT '请求参数', + user_agent varchar(500) COMMENT '用户代理', + ip varchar(32) COMMENT '操作IP', + error_info text COMMENT '异常信息', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + primary key (id), + key idx_create_date (create_date) +)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='异常日志'; + + +-- 文件上传 +CREATE TABLE sys_oss ( + id bigint NOT NULL COMMENT 'id', + url varchar(200) COMMENT 'URL地址', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + PRIMARY KEY (id), + key idx_create_date (create_date) +) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COMMENT='文件上传'; + +-- 定时任务 +CREATE TABLE schedule_job ( + id bigint NOT NULL COMMENT 'id', + bean_name varchar(200) DEFAULT NULL COMMENT 'spring bean名称', + params varchar(2000) DEFAULT NULL COMMENT '参数', + cron_expression varchar(100) DEFAULT NULL COMMENT 'cron表达式', + status tinyint unsigned COMMENT '任务状态 0:暂停 1:正常', + remark varchar(255) DEFAULT NULL COMMENT '备注', + creator bigint COMMENT '创建者', + create_date datetime COMMENT '创建时间', + updater bigint COMMENT '更新者', + update_date datetime COMMENT '更新时间', + PRIMARY KEY (id), + key idx_create_date (create_date) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='定时任务'; + +-- 定时任务日志 +CREATE TABLE schedule_job_log ( + id bigint NOT NULL COMMENT 'id', + job_id bigint NOT NULL COMMENT '任务id', + bean_name varchar(200) DEFAULT NULL COMMENT 'spring bean名称', + params varchar(2000) DEFAULT NULL COMMENT '参数', + status tinyint unsigned NOT NULL COMMENT '任务状态 0:失败 1:成功', + error varchar(2000) DEFAULT NULL COMMENT '失败信息', + times int NOT NULL COMMENT '耗时(单位:毫秒)', + create_date datetime COMMENT '创建时间', + PRIMARY KEY (id), + key idx_job_id (job_id), + key idx_create_date (create_date) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='定时任务日志'; + +-- 系统用户Token +CREATE TABLE sys_user_token ( + id bigint NOT NULL COMMENT 'id', + user_id bigint NOT NULL COMMENT '用户id', + token varchar(100) NOT NULL COMMENT '用户token', + expire_date datetime COMMENT '过期时间', + update_date datetime COMMENT '更新时间', + create_date datetime COMMENT '创建时间', + PRIMARY KEY (id), + UNIQUE KEY user_id (user_id), + UNIQUE KEY token (token) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户Token'; + +-- 初始数据 +INSERT INTO sys_user(id, username, password, real_name, gender, email, mobile, status, dept_id, super_admin, creator, create_date, updater, update_date) VALUES (1067246875800000001, 'admin', '$2a$10$012Kx2ba5jzqr9gLlG4MX.bnQJTD9UWqF57XDo2N3.fPtLne02u/m', '管理员', 0, 'root@renren.io', '13612345678', 1, null, 1, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000002, 0, '权限管理', NULL, NULL, 0, 'icon-safetycertificate', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000003, 1067246875800000055, '新增', NULL, 'sys:user:save,sys:dept:list,sys:role:list', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000004, 1067246875800000055, '修改', NULL, 'sys:user:update,sys:dept:list,sys:role:list', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000005, 1067246875800000055, '删除', NULL, 'sys:user:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000006, 1067246875800000055, '导出', NULL, 'sys:user:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000007, 1067246875800000002, '角色管理', 'sys/role', NULL, 0, 'icon-team', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000008, 1067246875800000007, '查看', NULL, 'sys:role:page,sys:role:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000009, 1067246875800000007, '新增', NULL, 'sys:role:save,sys:menu:select,sys:dept:list', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000010, 1067246875800000007, '修改', NULL, 'sys:role:update,sys:menu:select,sys:dept:list', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000011, 1067246875800000007, '删除', NULL, 'sys:role:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000012, 1067246875800000002, '部门管理', 'sys/dept', NULL, 0, 'icon-apartment', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000014, 1067246875800000012, '查看', NULL, 'sys:dept:list,sys:dept:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000015, 1067246875800000012, '新增', NULL, 'sys:dept:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000016, 1067246875800000012, '修改', NULL, 'sys:dept:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000017, 1067246875800000012, '删除', NULL, 'sys:dept:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000025, 1067246875800000035, '菜单管理', 'sys/menu', NULL, 0, 'icon-unorderedlist', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000026, 1067246875800000025, '查看', NULL, 'sys:menu:list,sys:menu:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000027, 1067246875800000025, '新增', NULL, 'sys:menu:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000028, 1067246875800000025, '修改', NULL, 'sys:menu:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000029, 1067246875800000025, '删除', NULL, 'sys:menu:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000030, 1067246875800000035, '定时任务', 'job/schedule', NULL, 0, 'icon-dashboard', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000031, 1067246875800000030, '查看', NULL, 'sys:schedule:page,sys:schedule:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000032, 1067246875800000030, '新增', NULL, 'sys:schedule:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000033, 1067246875800000030, '修改', NULL, 'sys:schedule:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000034, 1067246875800000030, '删除', NULL, 'sys:schedule:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000035, 0, '系统设置', NULL, NULL, 0, 'icon-setting', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000036, 1067246875800000030, '暂停', NULL, 'sys:schedule:pause', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000037, 1067246875800000030, '恢复', NULL, 'sys:schedule:resume', 1, NULL, 5, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000038, 1067246875800000030, '立即执行', NULL, 'sys:schedule:run', 1, NULL, 6, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000039, 1067246875800000030, '日志列表', NULL, 'sys:schedule:log', 1, NULL, 7, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000040, 1067246875800000035, '参数管理', 'sys/params', '', 0, 'icon-fileprotect', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000041, 1067246875800000035, '字典管理', 'sys/dict-type', NULL, 0, 'icon-golden-fill', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000042, 1067246875800000041, '查看', NULL, 'sys:dict:page,sys:dict:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000043, 1067246875800000041, '新增', NULL, 'sys:dict:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000044, 1067246875800000041, '修改', NULL, 'sys:dict:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000045, 1067246875800000041, '删除', NULL, 'sys:dict:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000046, 0, '日志管理', NULL, NULL, 0, 'icon-container', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000047, 1067246875800000035, '文件上传', 'oss/oss', 'sys:oss:all', 0, 'icon-upload', 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000048, 1067246875800000046, '登录日志', 'sys/log-login', 'sys:log:login', 0, 'icon-filedone', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000049, 1067246875800000046, '操作日志', 'sys/log-operation', 'sys:log:operation', 0, 'icon-solution', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000050, 1067246875800000046, '异常日志', 'sys/log-error', 'sys:log:error', 0, 'icon-file-exception', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000051, 1067246875800000053, 'SQL监控', '{{ window.SITE_CONFIG["apiURL"] }}/druid/sql.html', NULL, 0, 'icon-database', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000053, 0, '系统监控', NULL, NULL, 0, 'icon-desktop', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000055, 1067246875800000002, '用户管理', 'sys/user', NULL, 0, 'icon-user', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000056, 1067246875800000055, '查看', NULL, 'sys:user:page,sys:user:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000057, 1067246875800000040, '新增', NULL, 'sys:params:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000058, 1067246875800000040, '导出', NULL, 'sys:params:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000059, 1067246875800000040, '查看', '', 'sys:params:page,sys:params:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000060, 1067246875800000040, '修改', NULL, 'sys:params:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000061, 1067246875800000040, '删除', '', 'sys:params:delete', 1, '', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1156748733921165314, 1067246875800000053, '接口文档', '{{ window.SITE_CONFIG["apiURL"] }}/doc.html', '', 0, 'icon-file-word', 1, 1067246875800000001, now(), 1067246875800000001, now()); + + +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000062, 1067246875800000063, '1067246875800000066,1067246875800000063', '技术部', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000063, 1067246875800000066, '1067246875800000066', '长沙分公司', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000064, 1067246875800000066, '1067246875800000066', '上海分公司', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000065, 1067246875800000064, '1067246875800000066,1067246875800000064', '市场部', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000066, 0, '0', '人人开源集团', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000067, 1067246875800000064, '1067246875800000066,1067246875800000064', '销售部', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000068, 1067246875800000063, '1067246875800000066,1067246875800000063', '产品部', 1, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1160061077912858625, 'gender', '性别', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061112075464705, 1160061077912858625, '男', '0', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061146967879681, 1160061077912858625, '女', '1', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061190127267841, 1160061077912858625, '保密', '2', '', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1225813644059140097, 'notice_type', '站内通知-类型', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814069634195457, 1225813644059140097, '公告', '0', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814107559092225, 1225813644059140097, '会议', '1', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814271879340034, 1225813644059140097, '其他', '2', '', 2, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_params(id, param_code, param_value, param_type, remark, creator, create_date, updater, update_date) VALUES (1067246875800000073, 'CLOUD_STORAGE_CONFIG_KEY', '{"type":1,"qiniuDomain":"http://test.oss.renren.io","qiniuPrefix":"upload","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","qiniuBucketName":"renren-oss","aliyunDomain":"","aliyunPrefix":"","aliyunEndPoint":"","aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qcloudBucketName":""}', '0', '云存储配置信息', 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO schedule_job (id, bean_name, params, cron_expression, status, remark, creator, create_date, updater, update_date) VALUES (1067246875800000076, 'testTask', 'renren', '0 0/30 * * * ?', 0, '有参测试,多个参数使用json', 1067246875800000001, now(), 1067246875800000001, now()); + + +-- quartz自带表结构 +CREATE TABLE QRTZ_JOB_DETAILS( + SCHED_NAME VARCHAR(120) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + JOB_CLASS_NAME VARCHAR(250) NOT NULL, + IS_DURABLE VARCHAR(1) NOT NULL, + IS_NONCONCURRENT VARCHAR(1) NOT NULL, + IS_UPDATE_DATA VARCHAR(1) NOT NULL, + REQUESTS_RECOVERY VARCHAR(1) NOT NULL, + JOB_DATA BLOB NULL, + PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + NEXT_FIRE_TIME BIGINT(13) NULL, + PREV_FIRE_TIME BIGINT(13) NULL, + PRIORITY INTEGER NULL, + TRIGGER_STATE VARCHAR(16) NOT NULL, + TRIGGER_TYPE VARCHAR(8) NOT NULL, + START_TIME BIGINT(13) NOT NULL, + END_TIME BIGINT(13) NULL, + CALENDAR_NAME VARCHAR(200) NULL, + MISFIRE_INSTR SMALLINT(2) NULL, + JOB_DATA BLOB NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_SIMPLE_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + REPEAT_COUNT BIGINT(7) NOT NULL, + REPEAT_INTERVAL BIGINT(12) NOT NULL, + TIMES_TRIGGERED BIGINT(10) NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_CRON_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + CRON_EXPRESSION VARCHAR(120) NOT NULL, + TIME_ZONE_ID VARCHAR(80), + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_SIMPROP_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + STR_PROP_1 VARCHAR(512) NULL, + STR_PROP_2 VARCHAR(512) NULL, + STR_PROP_3 VARCHAR(512) NULL, + INT_PROP_1 INT NULL, + INT_PROP_2 INT NULL, + LONG_PROP_1 BIGINT NULL, + LONG_PROP_2 BIGINT NULL, + DEC_PROP_1 NUMERIC(13,4) NULL, + DEC_PROP_2 NUMERIC(13,4) NULL, + BOOL_PROP_1 VARCHAR(1) NULL, + BOOL_PROP_2 VARCHAR(1) NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_BLOB_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + BLOB_DATA BLOB NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_CALENDARS ( + SCHED_NAME VARCHAR(120) NOT NULL, + CALENDAR_NAME VARCHAR(200) NOT NULL, + CALENDAR BLOB NOT NULL, + PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_FIRED_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + ENTRY_ID VARCHAR(95) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + FIRED_TIME BIGINT(13) NOT NULL, + SCHED_TIME BIGINT(13) NOT NULL, + PRIORITY INTEGER NOT NULL, + STATE VARCHAR(16) NOT NULL, + JOB_NAME VARCHAR(200) NULL, + JOB_GROUP VARCHAR(200) NULL, + IS_NONCONCURRENT VARCHAR(1) NULL, + REQUESTS_RECOVERY VARCHAR(1) NULL, + PRIMARY KEY (SCHED_NAME,ENTRY_ID)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_SCHEDULER_STATE ( + SCHED_NAME VARCHAR(120) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + LAST_CHECKIN_TIME BIGINT(13) NOT NULL, + CHECKIN_INTERVAL BIGINT(13) NOT NULL, + PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE QRTZ_LOCKS ( + SCHED_NAME VARCHAR(120) NOT NULL, + LOCK_NAME VARCHAR(40) NOT NULL, + PRIMARY KEY (SCHED_NAME,LOCK_NAME)) + ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP); + +CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME); +CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); + +CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME); +CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); \ No newline at end of file diff --git a/renren-admin/db/oracle.sql b/renren-admin/db/oracle.sql new file mode 100644 index 0000000..d1468ea --- /dev/null +++ b/renren-admin/db/oracle.sql @@ -0,0 +1,684 @@ +CREATE TABLE sys_user ( + id NUMBER(20, 0) NOT NULL, + username varchar2(50) NOT NULL, + password varchar2(100), + real_name varchar2(50), + head_url varchar2(200), + gender NUMBER(2, 0), + email varchar2(100), + mobile varchar2(100), + dept_id NUMBER(20, 0), + super_admin NUMBER(2, 0), + status NUMBER(2, 0), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + primary key (id) +); + +CREATE UNIQUE INDEX uk_sys_user_username on sys_user(username); +CREATE INDEX idx_sys_user_create_date on sys_user(create_date); + +COMMENT ON TABLE sys_user IS '用户管理'; +COMMENT ON COLUMN sys_user.id IS 'id'; +COMMENT ON COLUMN sys_user.username IS '用户名'; +COMMENT ON COLUMN sys_user.password IS '密码'; +COMMENT ON COLUMN sys_user.real_name IS '姓名'; +COMMENT ON COLUMN sys_user.head_url IS '头像'; +COMMENT ON COLUMN sys_user.gender IS '性别 0:男 1:女 2:保密'; +COMMENT ON COLUMN sys_user.email IS '邮箱'; +COMMENT ON COLUMN sys_user.mobile IS '手机号'; +COMMENT ON COLUMN sys_user.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_user.super_admin IS '超级管理员 0:否 1:是'; +COMMENT ON COLUMN sys_user.status IS '状态 0:停用 1:正常'; +COMMENT ON COLUMN sys_user.creator IS '创建者'; +COMMENT ON COLUMN sys_user.create_date IS '创建时间'; +COMMENT ON COLUMN sys_user.updater IS '更新者'; +COMMENT ON COLUMN sys_user.update_date IS '更新时间'; + + +CREATE TABLE sys_dept ( + id NUMBER(20, 0) NOT NULL, + pid NUMBER(20, 0), + pids varchar2(500), + name varchar2(50), + sort NUMBER(10, 0), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + primary key (id) +); +CREATE INDEX idx_sys_dept_pid on sys_dept(pid); +CREATE INDEX idx_sys_dept_idx_sort on sys_dept(sort); + +COMMENT ON TABLE sys_dept IS '部门管理'; +COMMENT ON COLUMN sys_dept.id IS 'id'; +COMMENT ON COLUMN sys_dept.pid IS '上级ID'; +COMMENT ON COLUMN sys_dept.pids IS '所有上级ID,用逗号分开'; +COMMENT ON COLUMN sys_dept.name IS '部门名称'; +COMMENT ON COLUMN sys_dept.sort IS '排序'; +COMMENT ON COLUMN sys_dept.creator IS '创建者'; +COMMENT ON COLUMN sys_dept.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dept.updater IS '更新者'; +COMMENT ON COLUMN sys_dept.update_date IS '更新时间'; + + +create table sys_role +( + id NUMBER(20, 0) NOT NULL, + name varchar2(32), + remark varchar2(100), + dept_id NUMBER(20, 0), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + primary key (id) +); + +CREATE INDEX idx_sys_role_dept_id on sys_role(dept_id); + +COMMENT ON TABLE sys_role IS '角色管理'; +COMMENT ON COLUMN sys_role.id IS 'id'; +COMMENT ON COLUMN sys_role.name IS '角色名称'; +COMMENT ON COLUMN sys_role.remark IS '备注'; +COMMENT ON COLUMN sys_role.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_role.creator IS '创建者'; +COMMENT ON COLUMN sys_role.create_date IS '创建时间'; +COMMENT ON COLUMN sys_role.updater IS '更新者'; +COMMENT ON COLUMN sys_role.update_date IS '更新时间'; + + +create table sys_menu +( + id NUMBER(20, 0) NOT NULL, + pid NUMBER(20, 0), + name varchar2(200), + url varchar2(200), + permissions varchar2(500), + menu_type NUMBER(2, 0), + icon varchar2(50), + sort NUMBER(10, 0), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + primary key (id) +); + +CREATE INDEX idx_sys_menu_pid on sys_menu(pid); +CREATE INDEX idx_sys_menu_sort on sys_menu(sort); + +COMMENT ON TABLE sys_menu IS '菜单管理'; +COMMENT ON COLUMN sys_menu.id IS 'id'; +COMMENT ON COLUMN sys_menu.pid IS '上级ID,一级菜单为0'; +COMMENT ON COLUMN sys_menu.name IS '名称'; +COMMENT ON COLUMN sys_menu.url IS '菜单URL'; +COMMENT ON COLUMN sys_menu.permissions IS '授权(多个用逗号分隔,如:sys:user:list,sys:user:save)'; +COMMENT ON COLUMN sys_menu.menu_type IS '类型 0:菜单 1:按钮'; +COMMENT ON COLUMN sys_menu.icon IS '菜单图标'; +COMMENT ON COLUMN sys_menu.sort IS '排序'; +COMMENT ON COLUMN sys_menu.creator IS '创建者'; +COMMENT ON COLUMN sys_menu.create_date IS '创建时间'; +COMMENT ON COLUMN sys_menu.updater IS '更新者'; +COMMENT ON COLUMN sys_menu.update_date IS '更新时间'; + + +create table sys_role_user +( + id varchar2(32) NOT NULL, + role_id varchar2(32), + user_id varchar2(32), + creator varchar2(32), + create_date date, + primary key (id) +); + +CREATE INDEX idx_sys_role_user_role_id on sys_role_user(role_id); +CREATE INDEX idx_sys_role_user_user_id on sys_role_user(user_id); + +COMMENT ON TABLE sys_role_user IS '角色用户关系'; +COMMENT ON COLUMN sys_role_user.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_user.user_id IS '用户ID'; +COMMENT ON COLUMN sys_role_user.creator IS '创建者'; +COMMENT ON COLUMN sys_role_user.create_date IS '创建时间'; + + +create table sys_role_menu +( + id NUMBER(20, 0) NOT NULL, + role_id NUMBER(20, 0), + menu_id NUMBER(20, 0), + creator NUMBER(20, 0), + create_date date, + primary key (id) +); + +CREATE INDEX idx_sys_role_menu_role_id on sys_role_menu(role_id); +CREATE INDEX idx_sys_role_menu_menu_id on sys_role_menu(menu_id); + +COMMENT ON TABLE sys_role_menu IS '角色菜单关系'; +COMMENT ON COLUMN sys_role_menu.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_menu.menu_id IS '菜单ID'; +COMMENT ON COLUMN sys_role_menu.creator IS '创建者'; +COMMENT ON COLUMN sys_role_menu.create_date IS '创建时间'; + + +create table sys_role_data_scope +( + id NUMBER(20, 0) NOT NULL, + role_id NUMBER(20, 0), + dept_id NUMBER(20, 0), + creator NUMBER(20, 0), + create_date date, + primary key (id) +); +CREATE INDEX idx_data_scope_role_id on sys_role_data_scope(role_id); + +COMMENT ON TABLE sys_role_data_scope IS '角色数据权限'; +COMMENT ON COLUMN sys_role_data_scope.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_data_scope.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_role_data_scope.creator IS '创建者'; +COMMENT ON COLUMN sys_role_data_scope.create_date IS '创建时间'; + + +create table sys_params +( + id NUMBER(20, 0) NOT NULL, + param_code varchar2(32), + param_value varchar2(2000), + param_type NUMBER(2, 0) DEFAULT 1 NOT NULL, + remark varchar2(200), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_params_param_code on sys_params(param_code); +CREATE INDEX idx_sys_params_create_date on sys_params(create_date); + +COMMENT ON TABLE sys_params IS '参数管理'; +COMMENT ON COLUMN sys_params.param_code IS '参数编码'; +COMMENT ON COLUMN sys_params.param_value IS '参数值'; +COMMENT ON COLUMN sys_params.param_type IS '类型 0:系统参数 1:非系统参数'; +COMMENT ON COLUMN sys_params.remark IS '备注'; +COMMENT ON COLUMN sys_params.creator IS '创建者'; +COMMENT ON COLUMN sys_params.create_date IS '创建时间'; +COMMENT ON COLUMN sys_params.updater IS '更新者'; +COMMENT ON COLUMN sys_params.update_date IS '更新时间'; + + +create table sys_dict_type +( + id NUMBER(20, 0) NOT NULL, + dict_type varchar2(100), + dict_name varchar2(255), + remark varchar2(255), + sort NUMBER(10, 0), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_dict_type_dict_type on sys_dict_type(dict_type); + +COMMENT ON TABLE sys_dict_type IS '字典类型'; +COMMENT ON COLUMN sys_dict_type.id IS 'id'; +COMMENT ON COLUMN sys_dict_type.dict_type IS '字典类型'; +COMMENT ON COLUMN sys_dict_type.dict_name IS '字典名称'; +COMMENT ON COLUMN sys_dict_type.remark IS '备注'; +COMMENT ON COLUMN sys_dict_type.sort IS '排序'; +COMMENT ON COLUMN sys_dict_type.creator IS '创建者'; +COMMENT ON COLUMN sys_dict_type.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dict_type.updater IS '更新者'; +COMMENT ON COLUMN sys_dict_type.update_date IS '更新时间'; + +create table sys_dict_data +( + id NUMBER(20, 0) NOT NULL, + dict_type_id NUMBER(20, 0) NOT NULL, + dict_label varchar2(255), + dict_value varchar2(255), + remark varchar2(255), + sort NUMBER(10, 0), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + primary key (id) +); +CREATE INDEX idx_sys_dict_data_sort on sys_dict_data(sort); +CREATE UNIQUE INDEX uk_dict_type_value on sys_dict_data(dict_type_id, dict_value); + +COMMENT ON TABLE sys_dict_data IS '字典数据'; +COMMENT ON COLUMN sys_dict_data.id IS 'id'; +COMMENT ON COLUMN sys_dict_data.dict_type_id IS '字典类型ID'; +COMMENT ON COLUMN sys_dict_data.dict_label IS '字典标签'; +COMMENT ON COLUMN sys_dict_data.dict_value IS '字典值'; +COMMENT ON COLUMN sys_dict_data.remark IS '备注'; +COMMENT ON COLUMN sys_dict_data.sort IS '排序'; +COMMENT ON COLUMN sys_dict_data.creator IS '创建者'; +COMMENT ON COLUMN sys_dict_data.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dict_data.updater IS '更新者'; +COMMENT ON COLUMN sys_dict_data.update_date IS '更新时间'; + +create table sys_log_login +( + id NUMBER(20, 0) NOT NULL, + operation NUMBER(2, 0), + status NUMBER(2, 0), + user_agent varchar2(500), + ip varchar2(32), + creator_name varchar2(50), + creator NUMBER(20, 0), + create_date date, + primary key (id) +); +CREATE INDEX idx_login_status on sys_log_login(status); +CREATE INDEX idx_login_create_date on sys_log_login(create_date); + +COMMENT ON TABLE sys_log_login IS '登录日志'; +COMMENT ON COLUMN sys_log_login.id IS 'id'; +COMMENT ON COLUMN sys_log_login.operation IS '用户操作 0:用户登录 1:用户退出'; +COMMENT ON COLUMN sys_log_login.status IS '状态 0:失败 1:成功 2:账号已锁定'; +COMMENT ON COLUMN sys_log_login.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_login.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_login.creator_name IS '用户名'; +COMMENT ON COLUMN sys_log_login.creator IS '创建者'; +COMMENT ON COLUMN sys_log_login.create_date IS '创建时间'; + + +create table sys_log_operation +( + id NUMBER(20, 0) NOT NULL, + operation varchar2(50), + request_uri varchar2(200), + request_method varchar2(20), + request_params clob, + request_time NUMBER(10, 0), + user_agent varchar2(500), + ip varchar2(32), + status NUMBER(2, 0), + creator_name varchar2(50), + creator NUMBER(20, 0), + create_date date, + primary key (id) +); +CREATE INDEX idx_operation_create_date on sys_log_operation(create_date); + +COMMENT ON TABLE sys_log_operation IS '操作日志'; +COMMENT ON COLUMN sys_log_operation.id IS 'id'; +COMMENT ON COLUMN sys_log_operation.operation IS '用户操作'; +COMMENT ON COLUMN sys_log_operation.request_uri IS '请求URI'; +COMMENT ON COLUMN sys_log_operation.request_method IS '请求方式'; +COMMENT ON COLUMN sys_log_operation.request_params IS '请求参数'; +COMMENT ON COLUMN sys_log_operation.request_time IS '请求时长(毫秒)'; +COMMENT ON COLUMN sys_log_operation.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_operation.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_operation.status IS '状态 0:失败 1:成功'; +COMMENT ON COLUMN sys_log_operation.creator_name IS '用户名'; +COMMENT ON COLUMN sys_log_operation.creator IS '创建者'; +COMMENT ON COLUMN sys_log_operation.create_date IS '创建时间'; + + +create table sys_log_error +( + id NUMBER(20, 0) NOT NULL, + request_uri varchar2(200), + request_method varchar2(20), + request_params clob, + user_agent varchar2(500), + ip varchar2(32), + error_info clob, + creator NUMBER(20, 0), + create_date date, + primary key (id) +); +CREATE INDEX idx_error_create_date on sys_log_error(create_date); + +COMMENT ON TABLE sys_log_error IS '异常日志'; +COMMENT ON COLUMN sys_log_error.id IS 'id'; +COMMENT ON COLUMN sys_log_error.request_uri IS '请求URI'; +COMMENT ON COLUMN sys_log_error.request_method IS '请求方式'; +COMMENT ON COLUMN sys_log_error.request_params IS '请求参数'; +COMMENT ON COLUMN sys_log_error.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_error.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_error.error_info IS '异常信息'; +COMMENT ON COLUMN sys_log_error.creator IS '创建者'; +COMMENT ON COLUMN sys_log_error.create_date IS '创建时间'; + + +CREATE TABLE sys_oss ( + id NUMBER(20, 0) NOT NULL, + url varchar2(200), + creator NUMBER(20, 0), + create_date date, + PRIMARY KEY (id) +); +CREATE INDEX idx_sys_oss_create_date on sys_oss(create_date); + +COMMENT ON TABLE sys_oss IS '文件上传'; +COMMENT ON COLUMN sys_oss.id IS 'id'; +COMMENT ON COLUMN sys_oss.url IS 'URL地址'; +COMMENT ON COLUMN sys_mail_log.creator IS '创建者'; +COMMENT ON COLUMN sys_mail_log.create_date IS '创建时间'; + + +CREATE TABLE schedule_job ( + id NUMBER(20, 0) NOT NULL, + bean_name varchar2(200), + params varchar2(2000), + cron_expression varchar2(100), + status NUMBER(2, 0), + remark varchar2(255), + creator NUMBER(20, 0), + create_date date, + updater NUMBER(20, 0), + update_date date, + PRIMARY KEY (id) +); + +CREATE INDEX idx_schedule_job_create_date on schedule_job(create_date); + +COMMENT ON TABLE schedule_job IS '定时任务'; +COMMENT ON COLUMN schedule_job.id IS 'id'; +COMMENT ON COLUMN schedule_job.bean_name IS 'spring bean名称'; +COMMENT ON COLUMN schedule_job.params IS '参数'; +COMMENT ON COLUMN schedule_job.cron_expression IS 'cron表达式'; +COMMENT ON COLUMN schedule_job.status IS '任务状态 0:暂停 1:正常'; +COMMENT ON COLUMN schedule_job.remark IS '备注'; +COMMENT ON COLUMN schedule_job.creator IS '创建者'; +COMMENT ON COLUMN schedule_job.create_date IS '创建时间'; +COMMENT ON COLUMN schedule_job.updater IS '更新者'; +COMMENT ON COLUMN schedule_job.update_date IS '更新时间'; + + +CREATE TABLE schedule_job_log ( + id NUMBER(20, 0) NOT NULL, + job_id NUMBER(20, 0) NOT NULL, + bean_name varchar2(200), + params varchar2(2000), + status NUMBER(2, 0), + error varchar2(2000), + times NUMBER(10, 0), + create_date date, + PRIMARY KEY (id) +); + +CREATE INDEX idx_job_log_job_id on schedule_job_log(job_id); +CREATE INDEX idx_job_log_create_date on schedule_job_log(create_date); + +COMMENT ON TABLE schedule_job_log IS '定时任务日志'; +COMMENT ON COLUMN schedule_job_log.id IS 'id'; +COMMENT ON COLUMN schedule_job_log.bean_name IS 'spring bean名称'; +COMMENT ON COLUMN schedule_job_log.params IS '参数'; +COMMENT ON COLUMN schedule_job_log.status IS '任务状态 0:失败 1:成功'; +COMMENT ON COLUMN schedule_job_log.error IS '失败信息'; +COMMENT ON COLUMN schedule_job_log.times IS '耗时(单位:毫秒)'; +COMMENT ON COLUMN schedule_job.create_date IS '创建时间'; + + +CREATE TABLE sys_user_token ( + id NUMBER(20, 0) NOT NULL, + user_id NUMBER(20, 0), + token varchar2(100), + expire_date date, + update_date date, + create_date date, + PRIMARY KEY (id) +); + +CREATE UNIQUE INDEX uk_sys_user_token_user_id on sys_user_token(user_id); +CREATE UNIQUE INDEX uk_sys_user_token on sys_user_token(token); + +COMMENT ON TABLE sys_user_token IS '系统用户Token'; +COMMENT ON COLUMN sys_user_token.id IS 'id'; +COMMENT ON COLUMN sys_user_token.user_id IS '用户id'; +COMMENT ON COLUMN sys_user_token.token IS '用户token'; +COMMENT ON COLUMN sys_user_token.expire_date IS '过期时间'; +COMMENT ON COLUMN sys_user_token.update_date IS '更新时间'; +COMMENT ON COLUMN sys_user_token.create_date IS '创建时间'; + + + +-- 初始数据 +INSERT INTO sys_user(id, username, password, real_name, gender, email, mobile, status, dept_id, super_admin, creator, create_date, updater, update_date) VALUES (1067246875800000001, 'admin', '$2a$10$012Kx2ba5jzqr9gLlG4MX.bnQJTD9UWqF57XDo2N3.fPtLne02u/m', '管理员', 0, 'root@renren.io', '13612345678', 1, null, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); + +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000002, 0, '权限管理', NULL, NULL, 0, 'icon-safetycertificate', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000003, 1067246875800000055, '新增', NULL, 'sys:user:save,sys:dept:list,sys:role:list', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000004, 1067246875800000055, '修改', NULL, 'sys:user:update,sys:dept:list,sys:role:list', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000005, 1067246875800000055, '删除', NULL, 'sys:user:delete', 1, NULL, 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000006, 1067246875800000055, '导出', NULL, 'sys:user:export', 1, NULL, 4, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000007, 1067246875800000002, '角色管理', 'sys/role', NULL, 0, 'icon-team', 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000008, 1067246875800000007, '查看', NULL, 'sys:role:page,sys:role:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000009, 1067246875800000007, '新增', NULL, 'sys:role:save,sys:menu:select,sys:dept:list', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000010, 1067246875800000007, '修改', NULL, 'sys:role:update,sys:menu:select,sys:dept:list', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000011, 1067246875800000007, '删除', NULL, 'sys:role:delete', 1, NULL, 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000012, 1067246875800000002, '部门管理', 'sys/dept', NULL, 0, 'icon-apartment', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000014, 1067246875800000012, '查看', NULL, 'sys:dept:list,sys:dept:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000015, 1067246875800000012, '新增', NULL, 'sys:dept:save', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000016, 1067246875800000012, '修改', NULL, 'sys:dept:update', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000017, 1067246875800000012, '删除', NULL, 'sys:dept:delete', 1, NULL, 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000025, 1067246875800000035, '菜单管理', 'sys/menu', NULL, 0, 'icon-unorderedlist', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000026, 1067246875800000025, '查看', NULL, 'sys:menu:list,sys:menu:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000027, 1067246875800000025, '新增', NULL, 'sys:menu:save', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000028, 1067246875800000025, '修改', NULL, 'sys:menu:update', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000029, 1067246875800000025, '删除', NULL, 'sys:menu:delete', 1, NULL, 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000030, 1067246875800000035, '定时任务', 'job/schedule', NULL, 0, 'icon-dashboard', 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000031, 1067246875800000030, '查看', NULL, 'sys:schedule:page,sys:schedule:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000032, 1067246875800000030, '新增', NULL, 'sys:schedule:save', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000033, 1067246875800000030, '修改', NULL, 'sys:schedule:update', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000034, 1067246875800000030, '删除', NULL, 'sys:schedule:delete', 1, NULL, 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000035, 0, '系统设置', NULL, NULL, 0, 'icon-setting', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000036, 1067246875800000030, '暂停', NULL, 'sys:schedule:pause', 1, NULL, 4, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000037, 1067246875800000030, '恢复', NULL, 'sys:schedule:resume', 1, NULL, 5, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000038, 1067246875800000030, '立即执行', NULL, 'sys:schedule:run', 1, NULL, 6, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000039, 1067246875800000030, '日志列表', NULL, 'sys:schedule:log', 1, NULL, 7, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000040, 1067246875800000035, '参数管理', 'sys/params', '', 0, 'icon-fileprotect', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000041, 1067246875800000035, '字典管理', 'sys/dict-type', NULL, 0, 'icon-golden-fill', 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000042, 1067246875800000041, '查看', NULL, 'sys:dict:page,sys:dict:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000043, 1067246875800000041, '新增', NULL, 'sys:dict:save', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000044, 1067246875800000041, '修改', NULL, 'sys:dict:update', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000045, 1067246875800000041, '删除', NULL, 'sys:dict:delete', 1, NULL, 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000046, 0, '日志管理', NULL, NULL, 0, 'icon-container', 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000047, 1067246875800000035, '文件上传', 'oss/oss', 'sys:oss:all', 0, 'icon-upload', 4, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000048, 1067246875800000046, '登录日志', 'sys/log-login', 'sys:log:login', 0, 'icon-filedone', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000049, 1067246875800000046, '操作日志', 'sys/log-operation', 'sys:log:operation', 0, 'icon-solution', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000050, 1067246875800000046, '异常日志', 'sys/log-error', 'sys:log:error', 0, 'icon-file-exception', 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000051, 1067246875800000053, 'SQL监控', '{{ window.SITE_CONFIG["apiURL"] }}/druid/sql.html', NULL, 0, 'icon-database', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000053, 0, '系统监控', NULL, NULL, 0, 'icon-desktop', 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000055, 1067246875800000002, '用户管理', 'sys/user', NULL, 0, 'icon-user', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000056, 1067246875800000055, '查看', NULL, 'sys:user:page,sys:user:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000057, 1067246875800000040, '新增', NULL, 'sys:params:save', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000058, 1067246875800000040, '导出', NULL, 'sys:params:export', 1, NULL, 4, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000059, 1067246875800000040, '查看', '', 'sys:params:page,sys:params:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000060, 1067246875800000040, '修改', NULL, 'sys:params:update', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000061, 1067246875800000040, '删除', '', 'sys:params:delete', 1, '', 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1156748733921165314, 1067246875800000053, '接口文档', '{{ window.SITE_CONFIG["apiURL"] }}/doc.html', '', 0, 'icon-file-word', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); + + +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000062, 1067246875800000063, '1067246875800000066,1067246875800000063', '技术部', 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000063, 1067246875800000066, '1067246875800000066', '长沙分公司', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000064, 1067246875800000066, '1067246875800000066', '上海分公司', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000065, 1067246875800000064, '1067246875800000066,1067246875800000064', '市场部', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000066, 0, '0', '人人开源集团', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000067, 1067246875800000064, '1067246875800000066,1067246875800000064', '销售部', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000068, 1067246875800000063, '1067246875800000066,1067246875800000063', '产品部', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); + +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1160061077912858625, 'gender', '性别', '', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061112075464705, 1160061077912858625, '男', '0', '', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061146967879681, 1160061077912858625, '女', '1', '', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061190127267841, 1160061077912858625, '保密', '2', '', 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1225813644059140097, 'notice_type', '站内通知-类型', '', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814069634195457, 1225813644059140097, '公告', '0', '', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814107559092225, 1225813644059140097, '会议', '1', '', 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814271879340034, 1225813644059140097, '其他', '2', '', 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); + +INSERT INTO sys_params(id, param_code, param_value, param_type, remark, creator, create_date, updater, update_date) VALUES (1067246875800000073, 'CLOUD_STORAGE_CONFIG_KEY', '{"type":1,"qiniuDomain":"http://test.oss.renren.io","qiniuPrefix":"upload","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","qiniuBucketName":"renren-oss","aliyunDomain":"","aliyunPrefix":"","aliyunEndPoint":"","aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qcloudBucketName":""}', '0', '云存储配置信息', 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); + +INSERT INTO schedule_job (id, bean_name, params, cron_expression, status, remark, creator, create_date, updater, update_date) VALUES (1067246875800000076, 'testTask', 'renren', '0 0/30 * * * ?', 0, '有参测试,多个参数使用json', 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); + + +-- quartz自带表结构 +CREATE TABLE qrtz_job_details +( + SCHED_NAME VARCHAR2(120) NOT NULL, + JOB_NAME VARCHAR2(200) NOT NULL, + JOB_GROUP VARCHAR2(200) NOT NULL, + DESCRIPTION VARCHAR2(250) NULL, + JOB_CLASS_NAME VARCHAR2(250) NOT NULL, + IS_DURABLE VARCHAR2(1) NOT NULL, + IS_NONCONCURRENT VARCHAR2(1) NOT NULL, + IS_UPDATE_DATA VARCHAR2(1) NOT NULL, + REQUESTS_RECOVERY VARCHAR2(1) NOT NULL, + JOB_DATA BLOB NULL, + CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) +); +CREATE TABLE qrtz_triggers +( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + JOB_NAME VARCHAR2(200) NOT NULL, + JOB_GROUP VARCHAR2(200) NOT NULL, + DESCRIPTION VARCHAR2(250) NULL, + NEXT_FIRE_TIME NUMBER(13) NULL, + PREV_FIRE_TIME NUMBER(13) NULL, + PRIORITY NUMBER(13) NULL, + TRIGGER_STATE VARCHAR2(16) NOT NULL, + TRIGGER_TYPE VARCHAR2(8) NOT NULL, + START_TIME NUMBER(13) NOT NULL, + END_TIME NUMBER(13) NULL, + CALENDAR_NAME VARCHAR2(200) NULL, + MISFIRE_INSTR NUMBER(2) NULL, + JOB_DATA BLOB NULL, + CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) +); +CREATE TABLE qrtz_simple_triggers +( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + REPEAT_COUNT NUMBER(7) NOT NULL, + REPEAT_INTERVAL NUMBER(12) NOT NULL, + TIMES_TRIGGERED NUMBER(10) NOT NULL, + CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_cron_triggers +( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + CRON_EXPRESSION VARCHAR2(120) NOT NULL, + TIME_ZONE_ID VARCHAR2(80), + CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_simprop_triggers +( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + STR_PROP_1 VARCHAR2(512) NULL, + STR_PROP_2 VARCHAR2(512) NULL, + STR_PROP_3 VARCHAR2(512) NULL, + INT_PROP_1 NUMBER(10) NULL, + INT_PROP_2 NUMBER(10) NULL, + LONG_PROP_1 NUMBER(13) NULL, + LONG_PROP_2 NUMBER(13) NULL, + DEC_PROP_1 NUMERIC(13,4) NULL, + DEC_PROP_2 NUMERIC(13,4) NULL, + BOOL_PROP_1 VARCHAR2(1) NULL, + BOOL_PROP_2 VARCHAR2(1) NULL, + CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_blob_triggers +( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + BLOB_DATA BLOB NULL, + CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_calendars +( + SCHED_NAME VARCHAR2(120) NOT NULL, + CALENDAR_NAME VARCHAR2(200) NOT NULL, + CALENDAR BLOB NOT NULL, + CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) +); +CREATE TABLE qrtz_paused_trigger_grps +( + SCHED_NAME VARCHAR2(120) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) +); +CREATE TABLE qrtz_fired_triggers +( + SCHED_NAME VARCHAR2(120) NOT NULL, + ENTRY_ID VARCHAR2(95) NOT NULL, + TRIGGER_NAME VARCHAR2(200) NOT NULL, + TRIGGER_GROUP VARCHAR2(200) NOT NULL, + INSTANCE_NAME VARCHAR2(200) NOT NULL, + FIRED_TIME NUMBER(13) NOT NULL, + SCHED_TIME NUMBER(13) NOT NULL, + PRIORITY NUMBER(13) NOT NULL, + STATE VARCHAR2(16) NOT NULL, + JOB_NAME VARCHAR2(200) NULL, + JOB_GROUP VARCHAR2(200) NULL, + IS_NONCONCURRENT VARCHAR2(1) NULL, + REQUESTS_RECOVERY VARCHAR2(1) NULL, + CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID) +); +CREATE TABLE qrtz_scheduler_state +( + SCHED_NAME VARCHAR2(120) NOT NULL, + INSTANCE_NAME VARCHAR2(200) NOT NULL, + LAST_CHECKIN_TIME NUMBER(13) NOT NULL, + CHECKIN_INTERVAL NUMBER(13) NOT NULL, + CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) +); +CREATE TABLE qrtz_locks +( + SCHED_NAME VARCHAR2(120) NOT NULL, + LOCK_NAME VARCHAR2(40) NOT NULL, + CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME) +); + +create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP); + +create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME); +create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP); +create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE); +create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); +create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); + +create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME); +create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); +create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); + + diff --git a/renren-admin/db/postgresql.sql b/renren-admin/db/postgresql.sql new file mode 100644 index 0000000..2247476 --- /dev/null +++ b/renren-admin/db/postgresql.sql @@ -0,0 +1,699 @@ +CREATE TABLE sys_user ( + id int8 NOT NULL, + username varchar(50) NOT NULL, + password varchar(100), + real_name varchar(50), + head_url varchar(200), + gender int, + email varchar(100), + mobile varchar(100), + dept_id int8, + super_admin int, + status int, + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + primary key (id) +); + +CREATE UNIQUE INDEX uk_sys_user_username on sys_user(username); +CREATE INDEX idx_sys_user_create_date on sys_user(create_date); + +COMMENT ON TABLE sys_user IS '用户管理'; +COMMENT ON COLUMN sys_user.id IS 'id'; +COMMENT ON COLUMN sys_user.username IS '用户名'; +COMMENT ON COLUMN sys_user.password IS '密码'; +COMMENT ON COLUMN sys_user.real_name IS '姓名'; +COMMENT ON COLUMN sys_user.head_url IS '头像'; +COMMENT ON COLUMN sys_user.gender IS '性别 0:男 1:女 2:保密'; +COMMENT ON COLUMN sys_user.email IS '邮箱'; +COMMENT ON COLUMN sys_user.mobile IS '手机号'; +COMMENT ON COLUMN sys_user.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_user.super_admin IS '超级管理员 0:否 1:是'; +COMMENT ON COLUMN sys_user.status IS '状态 0:停用 1:正常'; +COMMENT ON COLUMN sys_user.creator IS '创建者'; +COMMENT ON COLUMN sys_user.create_date IS '创建时间'; +COMMENT ON COLUMN sys_user.updater IS '更新者'; +COMMENT ON COLUMN sys_user.update_date IS '更新时间'; + + +CREATE TABLE sys_dept ( + id int8 NOT NULL, + pid int8, + pids varchar(500), + name varchar(50), + sort int, + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + primary key (id) +); +CREATE INDEX idx_sys_dept_pid on sys_dept(pid); +CREATE INDEX idx_sys_dept_idx_sort on sys_dept(sort); + +COMMENT ON TABLE sys_dept IS '部门管理'; +COMMENT ON COLUMN sys_dept.id IS 'id'; +COMMENT ON COLUMN sys_dept.pid IS '上级ID'; +COMMENT ON COLUMN sys_dept.pids IS '所有上级ID,用逗号分开'; +COMMENT ON COLUMN sys_dept.name IS '部门名称'; +COMMENT ON COLUMN sys_dept.sort IS '排序'; +COMMENT ON COLUMN sys_dept.creator IS '创建者'; +COMMENT ON COLUMN sys_dept.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dept.updater IS '更新者'; +COMMENT ON COLUMN sys_dept.update_date IS '更新时间'; + + +create table sys_role +( + id int8 NOT NULL, + name varchar(50), + remark varchar(100), + dept_id int8, + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + primary key (id) +); + +CREATE INDEX idx_sys_role_dept_id on sys_role(dept_id); + +COMMENT ON TABLE sys_role IS '角色管理'; +COMMENT ON COLUMN sys_role.id IS 'id'; +COMMENT ON COLUMN sys_role.name IS '角色名称'; +COMMENT ON COLUMN sys_role.remark IS '备注'; +COMMENT ON COLUMN sys_role.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_role.creator IS '创建者'; +COMMENT ON COLUMN sys_role.create_date IS '创建时间'; +COMMENT ON COLUMN sys_role.updater IS '更新者'; +COMMENT ON COLUMN sys_role.update_date IS '更新时间'; + + +create table sys_menu +( + id int8 NOT NULL, + pid int8, + name varchar(200), + url varchar(200), + permissions varchar(500), + menu_type int, + icon varchar(50), + sort int, + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + primary key (id) +); + +CREATE INDEX idx_sys_menu_pid on sys_menu(pid); +CREATE INDEX idx_sys_menu_sort on sys_menu(sort); + +COMMENT ON TABLE sys_menu IS '菜单管理'; +COMMENT ON COLUMN sys_menu.id IS 'id'; +COMMENT ON COLUMN sys_menu.pid IS '上级ID,一级菜单为0'; +COMMENT ON COLUMN sys_menu.name IS '名称'; +COMMENT ON COLUMN sys_menu.url IS '菜单URL'; +COMMENT ON COLUMN sys_menu.permissions IS '授权(多个用逗号分隔,如:sys:user:list,sys:user:save)'; +COMMENT ON COLUMN sys_menu.menu_type IS '类型 0:菜单 1:按钮'; +COMMENT ON COLUMN sys_menu.icon IS '菜单图标'; +COMMENT ON COLUMN sys_menu.sort IS '排序'; +COMMENT ON COLUMN sys_menu.creator IS '创建者'; +COMMENT ON COLUMN sys_menu.create_date IS '创建时间'; +COMMENT ON COLUMN sys_menu.updater IS '更新者'; +COMMENT ON COLUMN sys_menu.update_date IS '更新时间'; + + +create table sys_role_user +( + id int8 NOT NULL, + role_id int8, + user_id int8, + creator int8, + create_date timestamp, + primary key (id) +); + +CREATE INDEX idx_sys_role_user_role_id on sys_role_user(role_id); +CREATE INDEX idx_sys_role_user_user_id on sys_role_user(user_id); + +COMMENT ON TABLE sys_role_user IS '角色用户关系'; +COMMENT ON COLUMN sys_role_user.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_user.user_id IS '用户ID'; +COMMENT ON COLUMN sys_role_user.creator IS '创建者'; +COMMENT ON COLUMN sys_role_user.create_date IS '创建时间'; + + +create table sys_role_menu +( + id int8 NOT NULL, + role_id int8, + menu_id int8, + creator int8, + create_date timestamp, + primary key (id) +); + +CREATE INDEX idx_sys_role_menu_role_id on sys_role_menu(role_id); +CREATE INDEX idx_sys_role_menu_menu_id on sys_role_menu(menu_id); + +COMMENT ON TABLE sys_role_menu IS '角色菜单关系'; +COMMENT ON COLUMN sys_role_menu.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_menu.menu_id IS '菜单ID'; +COMMENT ON COLUMN sys_role_menu.creator IS '创建者'; +COMMENT ON COLUMN sys_role_menu.create_date IS '创建时间'; + + +create table sys_role_data_scope +( + id int8 NOT NULL, + role_id int8, + dept_id int8, + creator int8, + create_date timestamp, + primary key (id) +); +CREATE INDEX idx_data_scope_role_id on sys_role_data_scope(role_id); + +COMMENT ON TABLE sys_role_data_scope IS '角色数据权限'; +COMMENT ON COLUMN sys_role_data_scope.role_id IS '角色ID'; +COMMENT ON COLUMN sys_role_data_scope.dept_id IS '部门ID'; +COMMENT ON COLUMN sys_role_data_scope.creator IS '创建者'; +COMMENT ON COLUMN sys_role_data_scope.create_date IS '创建时间'; + + +create table sys_params +( + id int8 NOT NULL, + param_code varchar(32), + param_value varchar(2000), + param_type int DEFAULT 1 NOT NULL, + remark varchar(200), + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_params_param_code on sys_params(param_code); +CREATE INDEX idx_sys_params_create_date on sys_params(create_date); + +COMMENT ON TABLE sys_params IS '参数管理'; +COMMENT ON COLUMN sys_params.param_code IS '参数编码'; +COMMENT ON COLUMN sys_params.param_value IS '参数值'; +COMMENT ON COLUMN sys_params.param_type IS '类型 0:系统参数 1:非系统参数'; +COMMENT ON COLUMN sys_params.remark IS '备注'; +COMMENT ON COLUMN sys_params.creator IS '创建者'; +COMMENT ON COLUMN sys_params.create_date IS '创建时间'; +COMMENT ON COLUMN sys_params.updater IS '更新者'; +COMMENT ON COLUMN sys_params.update_date IS '更新时间'; + + +create table sys_dict_type +( + id int8 NOT NULL, + dict_type varchar(100), + dict_name varchar(255), + remark varchar(255), + sort int, + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_dict_type_dict_type on sys_dict_type(dict_type); + +COMMENT ON TABLE sys_dict_type IS '字典类型'; +COMMENT ON COLUMN sys_dict_type.id IS 'id'; +COMMENT ON COLUMN sys_dict_type.dict_type IS '字典类型'; +COMMENT ON COLUMN sys_dict_type.dict_name IS '字典名称'; +COMMENT ON COLUMN sys_dict_type.remark IS '备注'; +COMMENT ON COLUMN sys_dict_type.sort IS '排序'; +COMMENT ON COLUMN sys_dict_type.creator IS '创建者'; +COMMENT ON COLUMN sys_dict_type.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dict_type.updater IS '更新者'; +COMMENT ON COLUMN sys_dict_type.update_date IS '更新时间'; + +create table sys_dict_data +( + id int8 NOT NULL, + dict_type_id int8 NOT NULL, + dict_label varchar(255), + dict_value varchar(255), + remark varchar(255), + sort int, + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + primary key (id) +); +CREATE INDEX idx_sys_dict_data_sort on sys_dict_data(sort); +CREATE UNIQUE INDEX uk_dict_type_value on sys_dict_data(dict_type_id, dict_value); + +COMMENT ON TABLE sys_dict_data IS '字典数据'; +COMMENT ON COLUMN sys_dict_data.id IS 'id'; +COMMENT ON COLUMN sys_dict_data.dict_type_id IS '字典类型ID'; +COMMENT ON COLUMN sys_dict_data.dict_label IS '字典标签'; +COMMENT ON COLUMN sys_dict_data.dict_value IS '字典值'; +COMMENT ON COLUMN sys_dict_data.remark IS '备注'; +COMMENT ON COLUMN sys_dict_data.sort IS '排序'; +COMMENT ON COLUMN sys_dict_data.creator IS '创建者'; +COMMENT ON COLUMN sys_dict_data.create_date IS '创建时间'; +COMMENT ON COLUMN sys_dict_data.updater IS '更新者'; +COMMENT ON COLUMN sys_dict_data.update_date IS '更新时间'; + + +create table sys_log_login +( + id int8 NOT NULL, + operation int, + status int, + user_agent varchar(500), + ip varchar(32), + creator_name varchar(50), + creator int8, + create_date timestamp, + primary key (id) +); +CREATE INDEX idx_login_status on sys_log_login(status); +CREATE INDEX idx_login_create_date on sys_log_login(create_date); + +COMMENT ON TABLE sys_log_login IS '登录日志'; +COMMENT ON COLUMN sys_log_login.id IS 'id'; +COMMENT ON COLUMN sys_log_login.operation IS '用户操作 0:用户登录 1:用户退出'; +COMMENT ON COLUMN sys_log_login.status IS '状态 0:失败 1:成功 2:账号已锁定'; +COMMENT ON COLUMN sys_log_login.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_login.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_login.creator_name IS '用户名'; +COMMENT ON COLUMN sys_log_login.creator IS '创建者'; +COMMENT ON COLUMN sys_log_login.create_date IS '创建时间'; + + +create table sys_log_operation +( + id int8 NOT NULL, + operation varchar(50), + request_uri varchar(200), + request_method varchar(20), + request_params text, + request_time int, + user_agent varchar(500), + ip varchar(32), + status int, + creator_name varchar(50), + creator int8, + create_date timestamp, + primary key (id) +); +CREATE INDEX idx_operation_create_date on sys_log_operation(create_date); + +COMMENT ON TABLE sys_log_operation IS '操作日志'; +COMMENT ON COLUMN sys_log_operation.id IS 'id'; +COMMENT ON COLUMN sys_log_operation.operation IS '用户操作'; +COMMENT ON COLUMN sys_log_operation.request_uri IS '请求URI'; +COMMENT ON COLUMN sys_log_operation.request_method IS '请求方式'; +COMMENT ON COLUMN sys_log_operation.request_params IS '请求参数'; +COMMENT ON COLUMN sys_log_operation.request_time IS '请求时长(毫秒)'; +COMMENT ON COLUMN sys_log_operation.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_operation.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_operation.status IS '状态 0:失败 1:成功'; +COMMENT ON COLUMN sys_log_operation.creator_name IS '用户名'; +COMMENT ON COLUMN sys_log_operation.creator IS '创建者'; +COMMENT ON COLUMN sys_log_operation.create_date IS '创建时间'; + + +create table sys_log_error +( + id int8 NOT NULL, + request_uri varchar(200), + request_method varchar(20), + request_params text, + user_agent varchar(500), + ip varchar(32), + error_info text, + creator int8, + create_date timestamp, + primary key (id) +); +CREATE INDEX idx_error_create_date on sys_log_error(create_date); + +COMMENT ON TABLE sys_log_error IS '异常日志'; +COMMENT ON COLUMN sys_log_error.id IS 'id'; +COMMENT ON COLUMN sys_log_error.request_uri IS '请求URI'; +COMMENT ON COLUMN sys_log_error.request_method IS '请求方式'; +COMMENT ON COLUMN sys_log_error.request_params IS '请求参数'; +COMMENT ON COLUMN sys_log_error.user_agent IS '用户代理'; +COMMENT ON COLUMN sys_log_error.ip IS '操作IP'; +COMMENT ON COLUMN sys_log_error.error_info IS '异常信息'; +COMMENT ON COLUMN sys_log_error.creator IS '创建者'; +COMMENT ON COLUMN sys_log_error.create_date IS '创建时间'; + + + +CREATE TABLE sys_oss ( + id int8 NOT NULL, + url varchar(200), + creator int8, + create_date timestamp, + PRIMARY KEY (id) +); +CREATE INDEX idx_sys_oss_create_date on sys_oss(create_date); + +COMMENT ON TABLE sys_oss IS '文件上传'; +COMMENT ON COLUMN sys_oss.id IS 'id'; +COMMENT ON COLUMN sys_oss.url IS 'URL地址'; +COMMENT ON COLUMN sys_oss.creator IS '创建者'; +COMMENT ON COLUMN sys_oss.create_date IS '创建时间'; + + +CREATE TABLE schedule_job ( + id int8 NOT NULL, + bean_name varchar(200), + params varchar(2000), + cron_expression varchar(100), + status int, + remark varchar(255), + creator int8, + create_date timestamp, + updater int8, + update_date timestamp, + PRIMARY KEY (id) +); + +CREATE INDEX idx_schedule_job_create_date on schedule_job(create_date); + +COMMENT ON TABLE schedule_job IS '定时任务'; +COMMENT ON COLUMN schedule_job.id IS 'id'; +COMMENT ON COLUMN schedule_job.bean_name IS 'spring bean名称'; +COMMENT ON COLUMN schedule_job.params IS '参数'; +COMMENT ON COLUMN schedule_job.cron_expression IS 'cron表达式'; +COMMENT ON COLUMN schedule_job.status IS '任务状态 0:暂停 1:正常'; +COMMENT ON COLUMN schedule_job.remark IS '备注'; +COMMENT ON COLUMN schedule_job.creator IS '创建者'; +COMMENT ON COLUMN schedule_job.create_date IS '创建时间'; +COMMENT ON COLUMN schedule_job.updater IS '更新者'; +COMMENT ON COLUMN schedule_job.update_date IS '更新时间'; + + +CREATE TABLE schedule_job_log ( + id int8 NOT NULL, + job_id int8 NOT NULL, + bean_name varchar(200), + params varchar(2000), + status int, + error varchar(2000), + times int, + create_date timestamp, + PRIMARY KEY (id) +); + +CREATE INDEX idx_job_log_job_id on schedule_job_log(job_id); +CREATE INDEX idx_job_log_create_date on schedule_job_log(create_date); + +COMMENT ON TABLE schedule_job_log IS '定时任务日志'; +COMMENT ON COLUMN schedule_job_log.id IS 'id'; +COMMENT ON COLUMN schedule_job_log.bean_name IS 'spring bean名称'; +COMMENT ON COLUMN schedule_job_log.params IS '参数'; +COMMENT ON COLUMN schedule_job_log.status IS '任务状态 0:失败 1:成功'; +COMMENT ON COLUMN schedule_job_log.error IS '失败信息'; +COMMENT ON COLUMN schedule_job_log.times IS '耗时(单位:毫秒)'; +COMMENT ON COLUMN schedule_job.create_date IS '创建时间'; + + +CREATE TABLE sys_user_token ( + id int8 NOT NULL, + user_id int8, + token varchar(100), + expire_date timestamp, + update_date timestamp, + create_date timestamp, + PRIMARY KEY (id) +); + +CREATE UNIQUE INDEX uk_sys_user_token_user_id on sys_user_token(user_id); +CREATE UNIQUE INDEX uk_sys_user_token on sys_user_token(token); + +COMMENT ON TABLE sys_user_token IS '系统用户Token'; +COMMENT ON COLUMN sys_user_token.id IS 'id'; +COMMENT ON COLUMN sys_user_token.user_id IS '用户id'; +COMMENT ON COLUMN sys_user_token.token IS '用户token'; +COMMENT ON COLUMN sys_user_token.expire_date IS '过期时间'; +COMMENT ON COLUMN sys_user_token.update_date IS '更新时间'; +COMMENT ON COLUMN sys_user_token.create_date IS '创建时间'; + + + +-- 初始数据 +INSERT INTO sys_user(id, username, password, real_name, gender, email, mobile, status, dept_id, super_admin, creator, create_date, updater, update_date) VALUES (1067246875800000001, 'admin', '$2a$10$012Kx2ba5jzqr9gLlG4MX.bnQJTD9UWqF57XDo2N3.fPtLne02u/m', '管理员', 0, 'root@renren.io', '13612345678', 1, null, 1, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000002, 0, '权限管理', NULL, NULL, 0, 'icon-safetycertificate', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000003, 1067246875800000055, '新增', NULL, 'sys:user:save,sys:dept:list,sys:role:list', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000004, 1067246875800000055, '修改', NULL, 'sys:user:update,sys:dept:list,sys:role:list', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000005, 1067246875800000055, '删除', NULL, 'sys:user:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000006, 1067246875800000055, '导出', NULL, 'sys:user:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000007, 1067246875800000002, '角色管理', 'sys/role', NULL, 0, 'icon-team', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000008, 1067246875800000007, '查看', NULL, 'sys:role:page,sys:role:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000009, 1067246875800000007, '新增', NULL, 'sys:role:save,sys:menu:select,sys:dept:list', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000010, 1067246875800000007, '修改', NULL, 'sys:role:update,sys:menu:select,sys:dept:list', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000011, 1067246875800000007, '删除', NULL, 'sys:role:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000012, 1067246875800000002, '部门管理', 'sys/dept', NULL, 0, 'icon-apartment', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000014, 1067246875800000012, '查看', NULL, 'sys:dept:list,sys:dept:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000015, 1067246875800000012, '新增', NULL, 'sys:dept:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000016, 1067246875800000012, '修改', NULL, 'sys:dept:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000017, 1067246875800000012, '删除', NULL, 'sys:dept:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000025, 1067246875800000035, '菜单管理', 'sys/menu', NULL, 0, 'icon-unorderedlist', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000026, 1067246875800000025, '查看', NULL, 'sys:menu:list,sys:menu:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000027, 1067246875800000025, '新增', NULL, 'sys:menu:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000028, 1067246875800000025, '修改', NULL, 'sys:menu:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000029, 1067246875800000025, '删除', NULL, 'sys:menu:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000030, 1067246875800000035, '定时任务', 'job/schedule', NULL, 0, 'icon-dashboard', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000031, 1067246875800000030, '查看', NULL, 'sys:schedule:page,sys:schedule:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000032, 1067246875800000030, '新增', NULL, 'sys:schedule:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000033, 1067246875800000030, '修改', NULL, 'sys:schedule:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000034, 1067246875800000030, '删除', NULL, 'sys:schedule:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000035, 0, '系统设置', NULL, NULL, 0, 'icon-setting', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000036, 1067246875800000030, '暂停', NULL, 'sys:schedule:pause', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000037, 1067246875800000030, '恢复', NULL, 'sys:schedule:resume', 1, NULL, 5, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000038, 1067246875800000030, '立即执行', NULL, 'sys:schedule:run', 1, NULL, 6, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000039, 1067246875800000030, '日志列表', NULL, 'sys:schedule:log', 1, NULL, 7, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000040, 1067246875800000035, '参数管理', 'sys/params', '', 0, 'icon-fileprotect', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000041, 1067246875800000035, '字典管理', 'sys/dict-type', NULL, 0, 'icon-golden-fill', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000042, 1067246875800000041, '查看', NULL, 'sys:dict:page,sys:dict:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000043, 1067246875800000041, '新增', NULL, 'sys:dict:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000044, 1067246875800000041, '修改', NULL, 'sys:dict:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000045, 1067246875800000041, '删除', NULL, 'sys:dict:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000046, 0, '日志管理', NULL, NULL, 0, 'icon-container', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000047, 1067246875800000035, '文件上传', 'oss/oss', 'sys:oss:all', 0, 'icon-upload', 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000048, 1067246875800000046, '登录日志', 'sys/log-login', 'sys:log:login', 0, 'icon-filedone', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000049, 1067246875800000046, '操作日志', 'sys/log-operation', 'sys:log:operation', 0, 'icon-solution', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000050, 1067246875800000046, '异常日志', 'sys/log-error', 'sys:log:error', 0, 'icon-file-exception', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000051, 1067246875800000053, 'SQL监控', '{{ window.SITE_CONFIG["apiURL"] }}/druid/sql.html', NULL, 0, 'icon-database', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000053, 0, '系统监控', NULL, NULL, 0, 'icon-desktop', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000055, 1067246875800000002, '用户管理', 'sys/user', NULL, 0, 'icon-user', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000056, 1067246875800000055, '查看', NULL, 'sys:user:page,sys:user:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000057, 1067246875800000040, '新增', NULL, 'sys:params:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000058, 1067246875800000040, '导出', NULL, 'sys:params:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000059, 1067246875800000040, '查看', '', 'sys:params:page,sys:params:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000060, 1067246875800000040, '修改', NULL, 'sys:params:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000061, 1067246875800000040, '删除', '', 'sys:params:delete', 1, '', 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1156748733921165314, 1067246875800000053, '接口文档', '{{ window.SITE_CONFIG["apiURL"] }}/doc.html', '', 0, 'icon-file-word', 1, 1067246875800000001, now(), 1067246875800000001, now()); + + +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000062, 1067246875800000063, '1067246875800000066,1067246875800000063', '技术部', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000063, 1067246875800000066, '1067246875800000066', '长沙分公司', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000064, 1067246875800000066, '1067246875800000066', '上海分公司', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000065, 1067246875800000064, '1067246875800000066,1067246875800000064', '市场部', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000066, 0, '0', '人人开源集团', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000067, 1067246875800000064, '1067246875800000066,1067246875800000064', '销售部', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000068, 1067246875800000063, '1067246875800000066,1067246875800000063', '产品部', 1, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1160061077912858625, 'gender', '性别', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061112075464705, 1160061077912858625, '男', '0', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061146967879681, 1160061077912858625, '女', '1', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061190127267841, 1160061077912858625, '保密', '2', '', 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1225813644059140097, 'notice_type', '站内通知-类型', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814069634195457, 1225813644059140097, '公告', '0', '', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814107559092225, 1225813644059140097, '会议', '1', '', 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814271879340034, 1225813644059140097, '其他', '2', '', 2, 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO sys_params(id, param_code, param_value, param_type, remark, creator, create_date, updater, update_date) VALUES (1067246875800000073, 'CLOUD_STORAGE_CONFIG_KEY', '{"type":1,"qiniuDomain":"http://test.oss.renren.io","qiniuPrefix":"upload","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","qiniuBucketName":"renren-oss","aliyunDomain":"","aliyunPrefix":"","aliyunEndPoint":"","aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qcloudBucketName":""}', '0', '云存储配置信息', 1067246875800000001, now(), 1067246875800000001, now()); + +INSERT INTO schedule_job (id, bean_name, params, cron_expression, status, remark, creator, create_date, updater, update_date) VALUES (1067246875800000076, 'testTask', 'renren', '0 0/30 * * * ?', 0, '有参测试,多个参数使用json', 1067246875800000001, now(), 1067246875800000001, now()); + + + +-- quartz自带表结构 +CREATE TABLE qrtz_job_details +( + SCHED_NAME VARCHAR(120) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + JOB_CLASS_NAME VARCHAR(250) NOT NULL, + IS_DURABLE BOOL NOT NULL, + IS_NONCONCURRENT BOOL NOT NULL, + IS_UPDATE_DATA BOOL NOT NULL, + REQUESTS_RECOVERY BOOL NOT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) +); + +CREATE TABLE qrtz_triggers +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + NEXT_FIRE_TIME BIGINT NULL, + PREV_FIRE_TIME BIGINT NULL, + PRIORITY INTEGER NULL, + TRIGGER_STATE VARCHAR(16) NOT NULL, + TRIGGER_TYPE VARCHAR(8) NOT NULL, + START_TIME BIGINT NOT NULL, + END_TIME BIGINT NULL, + CALENDAR_NAME VARCHAR(200) NULL, + MISFIRE_INSTR SMALLINT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) +); + +CREATE TABLE qrtz_simple_triggers +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + REPEAT_COUNT BIGINT NOT NULL, + REPEAT_INTERVAL BIGINT NOT NULL, + TIMES_TRIGGERED BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_cron_triggers +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + CRON_EXPRESSION VARCHAR(120) NOT NULL, + TIME_ZONE_ID VARCHAR(80), + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_simprop_triggers +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + STR_PROP_1 VARCHAR(512) NULL, + STR_PROP_2 VARCHAR(512) NULL, + STR_PROP_3 VARCHAR(512) NULL, + INT_PROP_1 INT NULL, + INT_PROP_2 INT NULL, + LONG_PROP_1 BIGINT NULL, + LONG_PROP_2 BIGINT NULL, + DEC_PROP_1 NUMERIC(13,4) NULL, + DEC_PROP_2 NUMERIC(13,4) NULL, + BOOL_PROP_1 BOOL NULL, + BOOL_PROP_2 BOOL NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_blob_triggers +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + BLOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_calendars +( + SCHED_NAME VARCHAR(120) NOT NULL, + CALENDAR_NAME VARCHAR(200) NOT NULL, + CALENDAR BYTEA NOT NULL, + PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) +); + + +CREATE TABLE qrtz_paused_trigger_grps +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) +); + +CREATE TABLE qrtz_fired_triggers +( + SCHED_NAME VARCHAR(120) NOT NULL, + ENTRY_ID VARCHAR(95) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + FIRED_TIME BIGINT NOT NULL, + SCHED_TIME BIGINT NOT NULL, + PRIORITY INTEGER NOT NULL, + STATE VARCHAR(16) NOT NULL, + JOB_NAME VARCHAR(200) NULL, + JOB_GROUP VARCHAR(200) NULL, + IS_NONCONCURRENT BOOL NULL, + REQUESTS_RECOVERY BOOL NULL, + PRIMARY KEY (SCHED_NAME,ENTRY_ID) +); + +CREATE TABLE qrtz_scheduler_state +( + SCHED_NAME VARCHAR(120) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + LAST_CHECKIN_TIME BIGINT NOT NULL, + CHECKIN_INTERVAL BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) +); + +CREATE TABLE qrtz_locks +( + SCHED_NAME VARCHAR(120) NOT NULL, + LOCK_NAME VARCHAR(40) NOT NULL, + PRIMARY KEY (SCHED_NAME,LOCK_NAME) +); + +create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP); + +create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME); +create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP); +create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE); +create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); +create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); +create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); +create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); + +create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME); +create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); +create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); +create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP); +create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); +create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); + + +commit; diff --git a/renren-admin/db/sqlserver.sql b/renren-admin/db/sqlserver.sql new file mode 100644 index 0000000..5915d64 --- /dev/null +++ b/renren-admin/db/sqlserver.sql @@ -0,0 +1,674 @@ +CREATE TABLE sys_user ( + id bigint NOT NULL, + username varchar(50) NOT NULL, + password varchar(100), + real_name varchar(50), + head_url varchar(200), + gender int, + email varchar(100), + mobile varchar(100), + dept_id bigint, + super_admin int, + status int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); + +CREATE UNIQUE INDEX uk_sys_user_username on sys_user(username); +CREATE INDEX idx_sys_user_create_date on sys_user(create_date); + + +CREATE TABLE sys_dept ( + id bigint NOT NULL, + pid bigint, + pids varchar(500), + name varchar(50), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE INDEX idx_sys_dept_pid on sys_dept(pid); +CREATE INDEX idx_sys_dept_idx_sort on sys_dept(sort); + + +create table sys_role +( + id bigint NOT NULL, + name varchar(50), + remark varchar(100), + dept_id bigint, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_role_dept_id on sys_role(dept_id); + + +create table sys_menu +( + id bigint NOT NULL, + pid bigint, + name varchar(200), + url varchar(200), + permissions varchar(500), + menu_type int, + icon varchar(50), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_menu_pid on sys_menu(pid); +CREATE INDEX idx_sys_menu_sort on sys_menu(sort); + + +create table sys_role_user +( + id bigint NOT NULL, + role_id bigint, + user_id bigint, + creator bigint, + create_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_role_user_role_id on sys_role_user(role_id); +CREATE INDEX idx_sys_role_user_user_id on sys_role_user(user_id); + + +create table sys_role_menu +( + id bigint NOT NULL, + role_id bigint, + menu_id bigint, + creator bigint, + create_date datetime, + primary key (id) +); + +CREATE INDEX idx_sys_role_menu_role_id on sys_role_menu(role_id); +CREATE INDEX idx_sys_role_menu_menu_id on sys_role_menu(menu_id); + + +create table sys_role_data_scope +( + id bigint NOT NULL, + role_id bigint, + dept_id bigint, + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_data_scope_role_id on sys_role_data_scope(role_id); + + +create table sys_params +( + id bigint NOT NULL, + param_code varchar(32), + param_value varchar(2000), + param_type int DEFAULT 1 NOT NULL, + remark varchar(200), + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_params_param_code on sys_params(param_code); +CREATE INDEX idx_sys_params_create_date on sys_params(create_date); + + +create table sys_dict_type +( + id bigint NOT NULL, + dict_type varchar(100), + dict_name varchar(255), + remark varchar(255), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE UNIQUE INDEX uk_sys_dict_type_dict_type on sys_dict_type(dict_type); + + +create table sys_dict_data +( + id bigint NOT NULL, + dict_type_id bigint NOT NULL, + dict_label varchar(255), + dict_value varchar(255), + remark varchar(255), + sort int, + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + primary key (id) +); +CREATE INDEX idx_sys_dict_data_sort on sys_dict_data(sort); +CREATE UNIQUE INDEX uk_dict_type_value on sys_dict_data(dict_type_id, dict_value); + + +create table sys_log_login +( + id bigint NOT NULL, + operation int, + status int, + user_agent varchar(500), + ip varchar(32), + creator_name varchar(50), + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_login_status on sys_log_login(status); +CREATE INDEX idx_login_create_date on sys_log_login(create_date); + + +create table sys_log_operation +( + id bigint NOT NULL, + operation varchar(50), + request_uri varchar(200), + request_method varchar(20), + request_params text, + request_time int, + user_agent varchar(500), + ip varchar(32), + status int, + creator_name varchar(50), + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_operation_create_date on sys_log_operation(create_date); + + +create table sys_log_error +( + id bigint NOT NULL, + request_uri varchar(200), + request_method varchar(20), + request_params text, + user_agent varchar(500), + ip varchar(32), + error_info text, + creator bigint, + create_date datetime, + primary key (id) +); +CREATE INDEX idx_error_create_date on sys_log_error(create_date); + + +CREATE TABLE sys_oss ( + id bigint NOT NULL, + url varchar(200), + creator bigint, + create_date datetime, + PRIMARY KEY (id) +); +CREATE INDEX idx_sys_oss_create_date on sys_oss(create_date); + + +CREATE TABLE schedule_job ( + id bigint NOT NULL, + bean_name varchar(200), + params varchar(2000), + cron_expression varchar(100), + status int, + remark varchar(255), + creator bigint, + create_date datetime, + updater bigint, + update_date datetime, + PRIMARY KEY (id) +); + +CREATE INDEX idx_schedule_job_create_date on schedule_job(create_date); + + +CREATE TABLE schedule_job_log ( + id bigint NOT NULL, + job_id bigint NOT NULL, + bean_name varchar(200), + params varchar(2000), + status int, + error varchar(2000), + times int, + create_date datetime, + PRIMARY KEY (id) +); + +CREATE INDEX idx_job_log_job_id on schedule_job_log(job_id); +CREATE INDEX idx_job_log_create_date on schedule_job_log(create_date); + + +CREATE TABLE sys_user_token ( + id bigint NOT NULL, + user_id bigint, + token varchar(100), + expire_date datetime, + update_date datetime, + create_date datetime, + PRIMARY KEY (id) +); + +CREATE UNIQUE INDEX uk_sys_user_token_user_id on sys_user_token(user_id); +CREATE UNIQUE INDEX uk_sys_user_token on sys_user_token(token); + + + +-- 初始数据 +INSERT INTO sys_user(id, username, password, real_name, gender, email, mobile, status, dept_id, super_admin, creator, create_date, updater, update_date) VALUES (1067246875800000001, 'admin', '$2a$10$012Kx2ba5jzqr9gLlG4MX.bnQJTD9UWqF57XDo2N3.fPtLne02u/m', '管理员', 0, 'root@renren.io', '13612345678', 1, null, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); + +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000002, 0, '权限管理', NULL, NULL, 0, 'icon-safetycertificate', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000003, 1067246875800000055, '新增', NULL, 'sys:user:save,sys:dept:list,sys:role:list', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000004, 1067246875800000055, '修改', NULL, 'sys:user:update,sys:dept:list,sys:role:list', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000005, 1067246875800000055, '删除', NULL, 'sys:user:delete', 1, NULL, 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000006, 1067246875800000055, '导出', NULL, 'sys:user:export', 1, NULL, 4, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000007, 1067246875800000002, '角色管理', 'sys/role', NULL, 0, 'icon-team', 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000008, 1067246875800000007, '查看', NULL, 'sys:role:page,sys:role:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000009, 1067246875800000007, '新增', NULL, 'sys:role:save,sys:menu:select,sys:dept:list', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000010, 1067246875800000007, '修改', NULL, 'sys:role:update,sys:menu:select,sys:dept:list', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000011, 1067246875800000007, '删除', NULL, 'sys:role:delete', 1, NULL, 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000012, 1067246875800000002, '部门管理', 'sys/dept', NULL, 0, 'icon-apartment', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000014, 1067246875800000012, '查看', NULL, 'sys:dept:list,sys:dept:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000015, 1067246875800000012, '新增', NULL, 'sys:dept:save', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000016, 1067246875800000012, '修改', NULL, 'sys:dept:update', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000017, 1067246875800000012, '删除', NULL, 'sys:dept:delete', 1, NULL, 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000025, 1067246875800000035, '菜单管理', 'sys/menu', NULL, 0, 'icon-unorderedlist', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000026, 1067246875800000025, '查看', NULL, 'sys:menu:list,sys:menu:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000027, 1067246875800000025, '新增', NULL, 'sys:menu:save', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000028, 1067246875800000025, '修改', NULL, 'sys:menu:update', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000029, 1067246875800000025, '删除', NULL, 'sys:menu:delete', 1, NULL, 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000030, 1067246875800000035, '定时任务', 'job/schedule', NULL, 0, 'icon-dashboard', 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000031, 1067246875800000030, '查看', NULL, 'sys:schedule:page,sys:schedule:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000032, 1067246875800000030, '新增', NULL, 'sys:schedule:save', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000033, 1067246875800000030, '修改', NULL, 'sys:schedule:update', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000034, 1067246875800000030, '删除', NULL, 'sys:schedule:delete', 1, NULL, 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000035, 0, '系统设置', NULL, NULL, 0, 'icon-setting', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000036, 1067246875800000030, '暂停', NULL, 'sys:schedule:pause', 1, NULL, 4, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000037, 1067246875800000030, '恢复', NULL, 'sys:schedule:resume', 1, NULL, 5, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000038, 1067246875800000030, '立即执行', NULL, 'sys:schedule:run', 1, NULL, 6, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000039, 1067246875800000030, '日志列表', NULL, 'sys:schedule:log', 1, NULL, 7, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000040, 1067246875800000035, '参数管理', 'sys/params', '', 0, 'icon-fileprotect', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000041, 1067246875800000035, '字典管理', 'sys/dict-type', NULL, 0, 'icon-golden-fill', 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000042, 1067246875800000041, '查看', NULL, 'sys:dict:page,sys:dict:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000043, 1067246875800000041, '新增', NULL, 'sys:dict:save', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000044, 1067246875800000041, '修改', NULL, 'sys:dict:update', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000045, 1067246875800000041, '删除', NULL, 'sys:dict:delete', 1, NULL, 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000046, 0, '日志管理', NULL, NULL, 0, 'icon-container', 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000047, 1067246875800000035, '文件上传', 'oss/oss', 'sys:oss:all', 0, 'icon-upload', 4, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000048, 1067246875800000046, '登录日志', 'sys/log-login', 'sys:log:login', 0, 'icon-filedone', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000049, 1067246875800000046, '操作日志', 'sys/log-operation', 'sys:log:operation', 0, 'icon-solution', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000050, 1067246875800000046, '异常日志', 'sys/log-error', 'sys:log:error', 0, 'icon-file-exception', 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000051, 1067246875800000053, 'SQL监控', '{{ window.SITE_CONFIG["apiURL"] }}/druid/sql.html', NULL, 0, 'icon-database', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000053, 0, '系统监控', NULL, NULL, 0, 'icon-desktop', 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000055, 1067246875800000002, '用户管理', 'sys/user', NULL, 0, 'icon-user', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000056, 1067246875800000055, '查看', NULL, 'sys:user:page,sys:user:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000057, 1067246875800000040, '新增', NULL, 'sys:params:save', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000058, 1067246875800000040, '导出', NULL, 'sys:params:export', 1, NULL, 4, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000059, 1067246875800000040, '查看', '', 'sys:params:page,sys:params:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000060, 1067246875800000040, '修改', NULL, 'sys:params:update', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1067246875800000061, 1067246875800000040, '删除', '', 'sys:params:delete', 1, '', 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu (id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (1156748733921165314, 1067246875800000053, '接口文档', '{{ window.SITE_CONFIG["apiURL"] }}/doc.html', '', 0, 'icon-file-word', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); + + +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000062, 1067246875800000063, '1067246875800000066,1067246875800000063', '技术部', 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000063, 1067246875800000066, '1067246875800000066', '长沙分公司', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000064, 1067246875800000066, '1067246875800000066', '上海分公司', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000065, 1067246875800000064, '1067246875800000066,1067246875800000064', '市场部', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000066, 0, '0', '人人开源集团', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000067, 1067246875800000064, '1067246875800000066,1067246875800000064', '销售部', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dept(id, pid, pids, name, sort, creator, create_date, updater, update_date) VALUES (1067246875800000068, 1067246875800000063, '1067246875800000066,1067246875800000063', '产品部', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); + +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1160061077912858625, 'gender', '性别', '', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061112075464705, 1160061077912858625, '男', '0', '', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061146967879681, 1160061077912858625, '女', '1', '', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1160061190127267841, 1160061077912858625, '保密', '2', '', 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dict_type(id, dict_type, dict_name, remark, sort, creator, create_date, updater, update_date) VALUES (1225813644059140097, 'notice_type', '站内通知-类型', '', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814069634195457, 1225813644059140097, '公告', '0', '', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814107559092225, 1225813644059140097, '会议', '1', '', 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_dict_data(id, dict_type_id, dict_label, dict_value, remark, sort, creator, create_date, updater, update_date) VALUES (1225814271879340034, 1225813644059140097, '其他', '2', '', 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); + +INSERT INTO sys_params(id, param_code, param_value, param_type, remark, creator, create_date, updater, update_date) VALUES (1067246875800000073, 'CLOUD_STORAGE_CONFIG_KEY', '{"type":1,"qiniuDomain":"http://test.oss.renren.io","qiniuPrefix":"upload","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","qiniuBucketName":"renren-oss","aliyunDomain":"","aliyunPrefix":"","aliyunEndPoint":"","aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qcloudBucketName":""}', '0', '云存储配置信息', 1067246875800000001, getdate(), 1067246875800000001, getdate()); + +INSERT INTO schedule_job (id, bean_name, params, cron_expression, status, remark, creator, create_date, updater, update_date) VALUES (1067246875800000076, 'testTask', 'renren', '0 0/30 * * * ?', 0, '有参测试,多个参数使用json', 1067246875800000001, getdate(), 1067246875800000001, getdate()); + + +-- quartz自带表结构 +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) + ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) + ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) + ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) + ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_CALENDARS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_LOCKS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_JOB_DETAILS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] +GO + +IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) + DROP TABLE [dbo].[QRTZ_TRIGGERS] +GO + +CREATE TABLE [dbo].[QRTZ_CALENDARS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [CALENDAR_NAME] [VARCHAR] (200) NOT NULL , + [CALENDAR] [IMAGE] NOT NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , + [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , + [CRON_EXPRESSION] [VARCHAR] (120) NOT NULL , + [TIME_ZONE_ID] [VARCHAR] (80) +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [ENTRY_ID] [VARCHAR] (95) NOT NULL , + [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , + [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , + [INSTANCE_NAME] [VARCHAR] (200) NOT NULL , + [FIRED_TIME] [BIGINT] NOT NULL , + [SCHED_TIME] [BIGINT] NOT NULL , + [PRIORITY] [INTEGER] NOT NULL , + [STATE] [VARCHAR] (16) NOT NULL, + [JOB_NAME] [VARCHAR] (200) NULL , + [JOB_GROUP] [VARCHAR] (200) NULL , + [IS_NONCONCURRENT] [VARCHAR] (1) NULL , + [REQUESTS_RECOVERY] [VARCHAR] (1) NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [INSTANCE_NAME] [VARCHAR] (200) NOT NULL , + [LAST_CHECKIN_TIME] [BIGINT] NOT NULL , + [CHECKIN_INTERVAL] [BIGINT] NOT NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_LOCKS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [LOCK_NAME] [VARCHAR] (40) NOT NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [JOB_NAME] [VARCHAR] (200) NOT NULL , + [JOB_GROUP] [VARCHAR] (200) NOT NULL , + [DESCRIPTION] [VARCHAR] (250) NULL , + [JOB_CLASS_NAME] [VARCHAR] (250) NOT NULL , + [IS_DURABLE] [VARCHAR] (1) NOT NULL , + [IS_NONCONCURRENT] [VARCHAR] (1) NOT NULL , + [IS_UPDATE_DATA] [VARCHAR] (1) NOT NULL , + [REQUESTS_RECOVERY] [VARCHAR] (1) NOT NULL , + [JOB_DATA] [IMAGE] NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , + [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , + [REPEAT_COUNT] [BIGINT] NOT NULL , + [REPEAT_INTERVAL] [BIGINT] NOT NULL , + [TIMES_TRIGGERED] [BIGINT] NOT NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , + [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , + [STR_PROP_1] [VARCHAR] (512) NULL, + [STR_PROP_2] [VARCHAR] (512) NULL, + [STR_PROP_3] [VARCHAR] (512) NULL, + [INT_PROP_1] [INT] NULL, + [INT_PROP_2] [INT] NULL, + [LONG_PROP_1] [BIGINT] NULL, + [LONG_PROP_2] [BIGINT] NULL, + [DEC_PROP_1] [NUMERIC] (13,4) NULL, + [DEC_PROP_2] [NUMERIC] (13,4) NULL, + [BOOL_PROP_1] [VARCHAR] (1) NULL, + [BOOL_PROP_2] [VARCHAR] (1) NULL, +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , + [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , + [BLOB_DATA] [IMAGE] NULL +) ON [PRIMARY] +GO + +CREATE TABLE [dbo].[QRTZ_TRIGGERS] ( + [SCHED_NAME] [VARCHAR] (120) NOT NULL , + [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , + [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , + [JOB_NAME] [VARCHAR] (200) NOT NULL , + [JOB_GROUP] [VARCHAR] (200) NOT NULL , + [DESCRIPTION] [VARCHAR] (250) NULL , + [NEXT_FIRE_TIME] [BIGINT] NULL , + [PREV_FIRE_TIME] [BIGINT] NULL , + [PRIORITY] [INTEGER] NULL , + [TRIGGER_STATE] [VARCHAR] (16) NOT NULL , + [TRIGGER_TYPE] [VARCHAR] (8) NOT NULL , + [START_TIME] [BIGINT] NOT NULL , + [END_TIME] [BIGINT] NULL , + [CALENDAR_NAME] [VARCHAR] (200) NULL , + [MISFIRE_INSTR] [SMALLINT] NULL , + [JOB_DATA] [IMAGE] NULL +) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [CALENDAR_NAME] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [ENTRY_ID] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [TRIGGER_GROUP] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [INSTANCE_NAME] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [LOCK_NAME] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [JOB_NAME], + [JOB_GROUP] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD + CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED + ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) ON [PRIMARY] +GO + +ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD + CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY + ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) ON DELETE CASCADE +GO + +ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD + CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY + ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) ON DELETE CASCADE +GO + +ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD + CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY + ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( + [SCHED_NAME], + [TRIGGER_NAME], + [TRIGGER_GROUP] + ) ON DELETE CASCADE +GO + +ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD + CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY + ( + [SCHED_NAME], + [JOB_NAME], + [JOB_GROUP] + ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] ( + [SCHED_NAME], + [JOB_NAME], + [JOB_GROUP] + ) +GO \ No newline at end of file diff --git a/renren-admin/pom.xml b/renren-admin/pom.xml new file mode 100644 index 0000000..ed12b5d --- /dev/null +++ b/renren-admin/pom.xml @@ -0,0 +1,156 @@ + + + io.renren + renren-security + 5.2.0 + + 4.0.0 + renren-admin + jar + renren-admin + + + 2.3.2 + 1.10.0 + 1.6.2 + 4.1.0 + 7.2.27 + 2.8.3 + 3.2.2 + 5.4.4 + + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.15.2 + + + com.alipay.sdk + alipay-sdk-java + 4.35.79.ALL + + + + org.apache.commons + commons-email + 1.5 + + + + io.renren + renren-common + 5.2.0 + + + io.renren + renren-dynamic-datasource + 5.2.0 + + + org.quartz-scheduler + quartz + ${quartz.version} + + + com.mchange + c3p0 + + + com.zaxxer + HikariCP-java6 + + + + + org.apache.shiro + shiro-core + ${shiro.version} + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + com.github.whvcse + easy-captcha + ${captcha.version} + + + cn.afterturn + easypoi-base + ${easypoi.version} + + + cn.afterturn + easypoi-web + ${easypoi.version} + + + cn.afterturn + easypoi-annotation + ${easypoi.version} + + + com.qiniu + qiniu-java-sdk + ${qiniu.version} + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun.oss.version} + + + com.aliyun + aliyun-java-sdk-core + ${aliyun.core.version} + + + com.qcloud + cos_api + ${qcloud.cos.version} + + + org.slf4j + slf4j-log4j12 + + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + com.spotify + docker-maven-plugin + ${docker.plugin.version} + + renren/${project.artifactId} + ${project.basedir}/ + + + / + ${project.build.directory} + ${project.build.finalName}.jar + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/AdminApplication.java b/renren-admin/src/main/java/io/renren/AdminApplication.java new file mode 100644 index 0000000..af283d9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/AdminApplication.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * renren-admin + * + * @author Mark sunlightcs@gmail.com + */ +@SpringBootApplication +@EnableTransactionManagement +@EnableCaching +public class AdminApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(AdminApplication.class, args); + } + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(AdminApplication.class); + } +} + diff --git a/renren-admin/src/main/java/io/renren/common/annotation/DataFilter.java b/renren-admin/src/main/java/io/renren/common/annotation/DataFilter.java new file mode 100644 index 0000000..108c7d0 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/annotation/DataFilter.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.annotation; + +import java.lang.annotation.*; + +/** + * 数据过滤注解 + * + * @author Mark sunlightcs@gmail.com + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface DataFilter { + /** + * 表的别名 + */ + String tableAlias() default ""; + + /** + * 用户ID + */ + String userId() default "creator"; + + /** + * 部门ID + */ + String deptId() default "dept_id"; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/annotation/LogOperation.java b/renren-admin/src/main/java/io/renren/common/annotation/LogOperation.java new file mode 100644 index 0000000..153306e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/annotation/LogOperation.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.annotation; + +import java.lang.annotation.*; + +/** + * 操作日志注解 + * + * @author Mark sunlightcs@gmail.com + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface LogOperation { + + String value() default ""; +} diff --git a/renren-admin/src/main/java/io/renren/common/aspect/DataFilterAspect.java b/renren-admin/src/main/java/io/renren/common/aspect/DataFilterAspect.java new file mode 100644 index 0000000..d0d5d07 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/aspect/DataFilterAspect.java @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.aspect; + +import cn.hutool.core.collection.CollUtil; +import io.renren.common.annotation.DataFilter; +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.common.interceptor.DataScope; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.enums.SuperAdminEnum; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; + +/** + * 数据过滤,切面处理类 + * + * @author Mark sunlightcs@gmail.com + */ +@Aspect +@Component +public class DataFilterAspect { + + @Pointcut("@annotation(io.renren.common.annotation.DataFilter)") + public void dataFilterCut() { + + } + + @Before("dataFilterCut()") + public void dataFilter(JoinPoint point) { + Object params = point.getArgs()[0]; + if(params != null && params instanceof Map){ + UserDetail user = SecurityUser.getUser(); + + //如果是超级管理员,则不进行数据过滤 + if(user.getSuperAdmin() == SuperAdminEnum.YES.value()) { + return ; + } + + try { + //否则进行数据过滤 + Map map = (Map)params; + String sqlFilter = getSqlFilter(user, point); + map.put(Constant.SQL_FILTER, new DataScope(sqlFilter)); + }catch (Exception e){ + + } + + return ; + } + + throw new RenException(ErrorCode.DATA_SCOPE_PARAMS_ERROR); + } + + /** + * 获取数据过滤的SQL + */ + private String getSqlFilter(UserDetail user, JoinPoint point) throws Exception { + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = point.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes()); + DataFilter dataFilter = method.getAnnotation(DataFilter.class); + + //获取表的别名 + String tableAlias = dataFilter.tableAlias(); + if(StringUtils.isNotBlank(tableAlias)){ + tableAlias += "."; + } + + StringBuilder sqlFilter = new StringBuilder(); + sqlFilter.append(" ("); + + //部门ID列表 + List deptIdList = user.getDeptIdList(); + if(CollUtil.isNotEmpty(deptIdList)){ + sqlFilter.append(tableAlias).append(dataFilter.deptId()); + + sqlFilter.append(" in(").append(StringUtils.join(deptIdList, ",")).append(")"); + } + + //查询本人数据 + if(CollUtil.isNotEmpty(deptIdList)){ + sqlFilter.append(" or "); + } + sqlFilter.append(tableAlias).append(dataFilter.userId()).append("=").append(user.getId()); + + sqlFilter.append(")"); + + return sqlFilter.toString(); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/aspect/LogOperationAspect.java b/renren-admin/src/main/java/io/renren/common/aspect/LogOperationAspect.java new file mode 100644 index 0000000..ec0eb8d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/aspect/LogOperationAspect.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.aspect; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.utils.HttpContextUtils; +import io.renren.common.utils.IpUtils; +import io.renren.common.utils.JsonUtils; +import io.renren.modules.log.entity.SysLogOperationEntity; +import io.renren.modules.log.enums.OperationStatusEnum; +import io.renren.modules.log.service.SysLogOperationService; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; + +/** + * 操作日志,切面处理类 + * + * @author Mark sunlightcs@gmail.com + */ +@Aspect +@Component +public class LogOperationAspect { + @Autowired + private SysLogOperationService sysLogOperationService; + + @Pointcut("@annotation(io.renren.common.annotation.LogOperation)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + try { + //执行方法 + Object result = point.proceed(); + + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + //保存日志 + saveLog(point, time, OperationStatusEnum.SUCCESS.value()); + + return result; + }catch(Exception e) { + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + //保存日志 + saveLog(point, time, OperationStatusEnum.FAIL.value()); + + throw e; + } + } + + private void saveLog(ProceedingJoinPoint joinPoint, long time, Integer status) throws Exception { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes()); + LogOperation annotation = method.getAnnotation(LogOperation.class); + + SysLogOperationEntity log = new SysLogOperationEntity(); + if(annotation != null){ + //注解上的描述 + log.setOperation(annotation.value()); + } + + //登录用户信息 + UserDetail user = SecurityUser.getUser(); + if(user != null){ + log.setCreatorName(user.getUsername()); + } + + log.setStatus(status); + log.setRequestTime((int)time); + + //请求相关信息 + HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + log.setRequestUri(request.getRequestURI()); + log.setRequestMethod(request.getMethod()); + + //请求参数 + Object[] args = joinPoint.getArgs(); + try{ + String params = JsonUtils.toJsonString(args[0]); + log.setRequestParams(params); + }catch (Exception e){ + + } + + //保存到DB + sysLogOperationService.save(log); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/config/MybatisPlusConfig.java b/renren-admin/src/main/java/io/renren/common/config/MybatisPlusConfig.java new file mode 100644 index 0000000..68e3fba --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/config/MybatisPlusConfig.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.config; + +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import io.renren.common.interceptor.DataFilterInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mybatis-plus配置 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Configuration +public class MybatisPlusConfig { + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); + // 数据权限 + mybatisPlusInterceptor.addInnerInterceptor(new DataFilterInterceptor()); + // 分页插件 + mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); + // 乐观锁 + mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); + // 防止全表更新与删除 + mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); + + return mybatisPlusInterceptor; + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/config/SwaggerConfig.java b/renren-admin/src/main/java/io/renren/common/config/SwaggerConfig.java new file mode 100644 index 0000000..135421a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/config/SwaggerConfig.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.config; + +import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; +import io.renren.common.constant.Constant; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; + +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +/** + * Swagger配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +@EnableSwagger2WebMvc +@AllArgsConstructor +public class SwaggerConfig{ + private final OpenApiExtensionResolver openApiExtensionResolver; + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + //加了ApiOperation注解的类,生成接口文档 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + //包下的类,生成接口文档 + //.apis(RequestHandlerSelectors.basePackage("io.renren.modules.job.controller")) + .paths(PathSelectors.any()) + .build() + .extensions(openApiExtensionResolver.buildExtensions("Renren")) + .directModelSubstitute(java.util.Date.class, String.class) + .securitySchemes(security()); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("人人开源") + .description("renren-admin文档") + .termsOfServiceUrl("https://www.renren.io") + .version("5.x") + .build(); + } + + private List security() { + return newArrayList( + new ApiKey(Constant.TOKEN_HEADER, Constant.TOKEN_HEADER, "header") + ); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/exception/RenExceptionHandler.java b/renren-admin/src/main/java/io/renren/common/exception/RenExceptionHandler.java new file mode 100644 index 0000000..2be058c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/exception/RenExceptionHandler.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.exception; + +import cn.hutool.core.map.MapUtil; +import io.renren.common.utils.HttpContextUtils; +import io.renren.common.utils.IpUtils; +import io.renren.common.utils.JsonUtils; +import io.renren.common.utils.Result; +import io.renren.modules.log.entity.SysLogErrorEntity; +import io.renren.modules.log.service.SysLogErrorService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + + +/** + * 异常处理器 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestControllerAdvice +public class RenExceptionHandler { + private static final Logger logger = LoggerFactory.getLogger(RenExceptionHandler.class); + + @Autowired + private SysLogErrorService sysLogErrorService; + + /** + * 处理自定义异常 + */ + @ExceptionHandler(RenException.class) + public Result handleRenException(RenException ex){ + Result result = new Result(); + result.error(ex.getCode(), ex.getMsg()); + + return result; + } + + @ExceptionHandler(DuplicateKeyException.class) + public Result handleDuplicateKeyException(DuplicateKeyException ex){ + Result result = new Result(); + result.error(ErrorCode.DB_RECORD_EXISTS); + + return result; + } + + @ExceptionHandler(Exception.class) + public Result handleException(Exception ex){ + logger.error(ex.getMessage(), ex); + + saveLog(ex); + + return new Result().error(); + } + + /** + * 保存异常日志 + */ + private void saveLog(Exception ex){ + SysLogErrorEntity log = new SysLogErrorEntity(); + + //请求相关信息 + HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + log.setRequestUri(request.getRequestURI()); + log.setRequestMethod(request.getMethod()); + Map params = HttpContextUtils.getParameterMap(request); + if(MapUtil.isNotEmpty(params)){ + log.setRequestParams(JsonUtils.toJsonString(params)); + } + + //异常信息 + log.setErrorInfo(ExceptionUtils.getErrorStackTrace(ex)); + + //保存 + sysLogErrorService.save(log); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/handler/FieldMetaObjectHandler.java b/renren-admin/src/main/java/io/renren/common/handler/FieldMetaObjectHandler.java new file mode 100644 index 0000000..26ffd93 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/handler/FieldMetaObjectHandler.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.handler; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import io.renren.modules.front.utils.BaseContext; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 公共字段,自动填充值 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class FieldMetaObjectHandler implements MetaObjectHandler { + private final static String CREATE_DATE = "createDate"; + private final static String CREATOR = "creator"; + private final static String UPDATE_DATE = "updateDate"; + private final static String UPDATER = "updater"; + private final static String DEPT_ID = "deptId"; + + private static final String TARGET_PACKAGE = "io.renren.modules.front.bean"; + + @Override + public void insertFill(MetaObject metaObject) { + String className = metaObject.getOriginalObject().getClass().getName(); + if (className.startsWith(TARGET_PACKAGE)){ + //填充前台页面相关公共字段 + metaObject.setValue(CREATOR, BaseContext.getCurrentId()); + metaObject.setValue(CREATE_DATE, LocalDateTime.now()); + metaObject.setValue(UPDATER, BaseContext.getCurrentId()); + metaObject.setValue(UPDATE_DATE, LocalDateTime.now()); + }else { + //填充后台页面相关公共字段 + UserDetail user = SecurityUser.getUser(); + Date date = new Date(); + + //创建者 + strictInsertFill(metaObject, CREATOR, Long.class, user.getId()); + //创建时间 + strictInsertFill(metaObject, CREATE_DATE, Date.class, date); + + //创建者所属部门 + strictInsertFill(metaObject, DEPT_ID, Long.class, user.getDeptId()); + + //更新者 + strictInsertFill(metaObject, UPDATER, Long.class, user.getId()); + //更新时间 + strictInsertFill(metaObject, UPDATE_DATE, Date.class, date); + } + } + + @Override + public void updateFill(MetaObject metaObject) { + String className = metaObject.getOriginalObject().getClass().getName(); + if (className.startsWith(TARGET_PACKAGE)){ + //填充前台页面相关公共字段 + metaObject.setValue(UPDATER, BaseContext.getCurrentId()); + metaObject.setValue(UPDATE_DATE, LocalDateTime.now()); + }else { + //更新者 + strictUpdateFill(metaObject, UPDATER, Long.class, SecurityUser.getUserId()); + //更新时间 + strictUpdateFill(metaObject, UPDATE_DATE, Date.class, new Date()); + } + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/interceptor/DataFilterInterceptor.java b/renren-admin/src/main/java/io/renren/common/interceptor/DataFilterInterceptor.java new file mode 100644 index 0000000..87cb0b2 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/interceptor/DataFilterInterceptor.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.interceptor; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.toolkit.PluginUtils; +import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.StringValue; +import net.sf.jsqlparser.expression.operators.conditional.AndExpression; +import net.sf.jsqlparser.parser.CCJSqlParserUtil; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.Select; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; + +import java.util.Map; + +/** + * 数据过滤 + * + * @author Mark sunlightcs@gmail.com + */ +public class DataFilterInterceptor implements InnerInterceptor { + + @Override + public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { + DataScope scope = getDataScope(parameter); + // 不进行数据过滤 + if(scope == null || StrUtil.isBlank(scope.getSqlFilter())){ + return; + } + + // 拼接新SQL + String buildSql = getSelect(boundSql.getSql(), scope); + + // 重写SQL + PluginUtils.mpBoundSql(boundSql).sql(buildSql); + } + + private DataScope getDataScope(Object parameter){ + if (parameter == null){ + return null; + } + + // 判断参数里是否有DataScope对象 + if (parameter instanceof Map) { + Map parameterMap = (Map) parameter; + for (Map.Entry entry : parameterMap.entrySet()) { + if (entry.getValue() != null && entry.getValue() instanceof DataScope) { + return (DataScope) entry.getValue(); + } + } + } else if (parameter instanceof DataScope) { + return (DataScope) parameter; + } + + return null; + } + + private String getSelect(String buildSql, DataScope scope){ + try { + Select select = (Select) CCJSqlParserUtil.parse(buildSql); + PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); + + Expression expression = plainSelect.getWhere(); + if(expression == null){ + plainSelect.setWhere(new StringValue(scope.getSqlFilter())); + }else{ + AndExpression andExpression = new AndExpression(expression, new StringValue(scope.getSqlFilter())); + plainSelect.setWhere(andExpression); + } + + return select.toString().replaceAll("'", ""); + }catch (JSQLParserException e){ + return buildSql; + } + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/interceptor/DataScope.java b/renren-admin/src/main/java/io/renren/common/interceptor/DataScope.java new file mode 100644 index 0000000..11acdd2 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/interceptor/DataScope.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.interceptor; + +/** + * 数据范围 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class DataScope { + private String sqlFilter; + + public DataScope(String sqlFilter) { + this.sqlFilter = sqlFilter; + } + + public String getSqlFilter() { + return sqlFilter; + } + + public void setSqlFilter(String sqlFilter) { + this.sqlFilter = sqlFilter; + } + + @Override + public String toString() { + return this.sqlFilter; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/common/utils/ExcelUtils.java b/renren-admin/src/main/java/io/renren/common/utils/ExcelUtils.java new file mode 100644 index 0000000..cc9256c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/utils/ExcelUtils.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.beans.BeanUtils; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * excel工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ExcelUtils { + + /** + * Excel导出 + * + * @param response response + * @param fileName 文件名 + * @param list 数据List + * @param pojoClass 对象Class + */ + public static void exportExcel(HttpServletResponse response, String fileName, Collection list, + Class pojoClass) throws IOException { + if(StringUtils.isBlank(fileName)){ + //当前日期 + fileName = DateUtils.format(new Date()); + } + + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), pojoClass, list); + response.setCharacterEncoding("UTF-8"); + response.setHeader("content-Type", "application/vnd.ms-excel"); + response.setHeader("Content-Disposition", + "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls"); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } + + /** + * Excel导出,先sourceList转换成List,再导出 + * + * @param response response + * @param fileName 文件名 + * @param sourceList 原数据List + * @param targetClass 目标对象Class + */ + public static void exportExcelToTarget(HttpServletResponse response, String fileName, Collection sourceList, + Class targetClass) throws Exception { + List targetList = new ArrayList<>(sourceList.size()); + for(Object source : sourceList){ + Object target = targetClass.newInstance(); + BeanUtils.copyProperties(source, target); + targetList.add(target); + } + + exportExcel(response, fileName, targetList, targetClass); + } +} diff --git a/renren-admin/src/main/java/io/renren/common/validator/group/AliyunGroup.java b/renren-admin/src/main/java/io/renren/common/validator/group/AliyunGroup.java new file mode 100644 index 0000000..d8e7b5c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/validator/group/AliyunGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 阿里云 + * + * @author Mark sunlightcs@gmail.com + */ +public interface AliyunGroup { +} diff --git a/renren-admin/src/main/java/io/renren/common/validator/group/QcloudGroup.java b/renren-admin/src/main/java/io/renren/common/validator/group/QcloudGroup.java new file mode 100644 index 0000000..376e988 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/validator/group/QcloudGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 腾讯云 + * + * @author Mark sunlightcs@gmail.com + */ +public interface QcloudGroup { +} diff --git a/renren-admin/src/main/java/io/renren/common/validator/group/QiniuGroup.java b/renren-admin/src/main/java/io/renren/common/validator/group/QiniuGroup.java new file mode 100644 index 0000000..542018b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/common/validator/group/QiniuGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 七牛 + * + * @author Mark sunlightcs@gmail.com + */ +public interface QiniuGroup { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/AddressBook.java b/renren-admin/src/main/java/io/renren/modules/front/bean/AddressBook.java new file mode 100644 index 0000000..b4b37ae --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/AddressBook.java @@ -0,0 +1,121 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 地址管理(AddressBook)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:55 + */ +@Data +@NoArgsConstructor +@TableName("address_book") +public class AddressBook implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 收货人 + */ + private String consignee; + + /** + * 性别 0 男 1 女 + */ + private Integer gender; + + /** + * 手机号 + */ + private String phone; + + /** + * 省级区划编号 + */ + private String provinceCode; + + /** + * 省级名称 + */ + private String provinceName; + + /** + * 市级区划编号 + */ + private String cityCode; + + /** + * 市级名称 + */ + private String cityName; + + /** + * 区级区划编号 + */ + private String districtCode; + + /** + * 区级名称 + */ + private String districtName; + + /** + * 详细地址 + */ + private String detail; + + /** + * 标签 + */ + private String label; + + /** + * 默认 0 否 1是 + */ + private Integer isDefault; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateDate; + + /** + * 是否删除 + */ + private Integer isDeleted; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/Category.java b/renren-admin/src/main/java/io/renren/modules/front/bean/Category.java new file mode 100644 index 0000000..8f2a5d1 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/Category.java @@ -0,0 +1,66 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 菜品及套餐分类(Category)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("category") +public class Category implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 类型 1 菜品分类 2 套餐分类 + */ + private Integer type; + + /** + * 分类名称 + */ + private String name; + + /** + * 顺序 + */ + private Integer sort; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/Dish.java b/renren-admin/src/main/java/io/renren/modules/front/bean/Dish.java new file mode 100644 index 0000000..849d409 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/Dish.java @@ -0,0 +1,104 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 菜品管理(Dish)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("dish") +public class Dish implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 菜品名称 + */ + private String name; + + /** + * 菜品分类id + */ + private Long categoryId; + + /** + * 菜品价格 + */ + private Double price; + + /** + * 商品码 + */ + private String code; + + /** + * 图片 + */ + private String image; + + /** + * 描述信息 + */ + private String description; + + /** + * 0 停售 1 起售 + */ + private Integer status; + + /** + * 顺序 + */ + private Integer sort; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + @JsonSerialize(using = LocalDateTimeSerializer.class)// 序列化 + @JsonDeserialize(using = LocalDateTimeDeserializer.class)// 反序列化 + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @JsonSerialize(using = LocalDateTimeSerializer.class)// 序列化 + @JsonDeserialize(using = LocalDateTimeDeserializer.class)// 反序列化 + private LocalDateTime updateDate; + + /** + * 是否删除 + */ + private Integer isDeleted; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/DishFlavor.java b/renren-admin/src/main/java/io/renren/modules/front/bean/DishFlavor.java new file mode 100644 index 0000000..0aea790 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/DishFlavor.java @@ -0,0 +1,79 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 菜品口味关系表(DishFlavor)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("dish_flavor") +public class DishFlavor implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 菜品 + */ + private Long dishId; + + /** + * 口味名称 + */ + private String name; + + /** + * 口味数据list + */ + private String value; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + @JsonSerialize(using = LocalDateTimeSerializer.class)// 序列化 + @JsonDeserialize(using = LocalDateTimeDeserializer.class)// 反序列化 + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + @JsonSerialize(using = LocalDateTimeSerializer.class)// 序列化 + @JsonDeserialize(using = LocalDateTimeDeserializer.class)// 反序列化 + private LocalDateTime updateDate; + + /** + * 是否删除 + */ + private Integer isDeleted; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/OrderDetail.java b/renren-admin/src/main/java/io/renren/modules/front/bean/OrderDetail.java new file mode 100644 index 0000000..9c501a7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/OrderDetail.java @@ -0,0 +1,69 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 订单明细表(OrderDetail)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("order_detail") +public class OrderDetail implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 名字 + */ + private String name; + + /** + * 图片 + */ + private String image; + + /** + * 订单id + */ + private Long orderId; + + /** + * 菜品id + */ + private Long dishId; + + /** + * 套餐id + */ + private Long setmealId; + + /** + * 口味 + */ + private String dishFlavor; + + /** + * 数量 + */ + private Integer number; + + /** + * 金额 + */ + private BigDecimal amount; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/Orders.java b/renren-admin/src/main/java/io/renren/modules/front/bean/Orders.java new file mode 100644 index 0000000..39f1e22 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/Orders.java @@ -0,0 +1,83 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 订单表(Orders)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("orders") +public class Orders implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 订单号 + */ + private String number; + + /** + * 订单状态 1待付款,2待派送,3已派送,4已完成,5已取消 + */ + private Integer status; + + /** + * 下单用户 + */ + private Long userId; + + /** + * 地址id + */ + private Long addressBookId; + + /** + * 下单时间 + */ + private LocalDateTime orderTime; + + /** + * 结账时间 + */ + private LocalDateTime checkoutTime; + + /** + * 支付方式 1微信,2支付宝 + */ + private Integer payMethod; + + /** + * 实收金额 + */ + private BigDecimal amount; + + /** + * 备注 + */ + private String remark; + + private String phone; + + private String address; + + private String userName; + + private String consignee; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/Setmeal.java b/renren-admin/src/main/java/io/renren/modules/front/bean/Setmeal.java new file mode 100644 index 0000000..617fc09 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/Setmeal.java @@ -0,0 +1,91 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 套餐(Setmeal)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("setmeal") +public class Setmeal implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 菜品分类id + */ + private Long categoryId; + + /** + * 套餐名称 + */ + private String name; + + /** + * 套餐价格 + */ + private Double price; + + /** + * 状态 0:停用 1:启用 + */ + private Integer status; + + /** + * 编码 + */ + private String code; + + /** + * 描述信息 + */ + private String description; + + /** + * 图片 + */ + private String image; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateDate; + + /** + * 是否删除 + */ + private Integer isDeleted; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/SetmealDish.java b/renren-admin/src/main/java/io/renren/modules/front/bean/SetmealDish.java new file mode 100644 index 0000000..560fedf --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/SetmealDish.java @@ -0,0 +1,86 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 套餐菜品关系(SetmealDish)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("setmeal_dish") +public class SetmealDish implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 套餐id + */ + private String setmealId; + + /** + * 菜品id + */ + private String dishId; + + /** + * 菜品名称 (冗余字段) + */ + private String name; + + /** + * 菜品原价(冗余字段) + */ + private Double price; + + /** + * 份数 + */ + private Integer copies; + + /** + * 排序 + */ + private Integer sort; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateDate; + + /** + * 是否删除 + */ + private Integer isDeleted; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/ShoppingCart.java b/renren-admin/src/main/java/io/renren/modules/front/bean/ShoppingCart.java new file mode 100644 index 0000000..a61b123 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/ShoppingCart.java @@ -0,0 +1,92 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 购物车(ShoppingCart)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("shopping_cart") +public class ShoppingCart implements Serializable { + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 名称 + */ + private String name; + + /** + * 图片 + */ + private String image; + + /** + * 主键 + */ + private Long userId; + + /** + * 菜品id + */ + private Long dishId; + + /** + * 套餐id + */ + private Long setmealId; + + /** + * 口味 + */ + private String dishFlavor; + + /** + * 数量 + */ + private Integer number; + + /** + * 金额 + */ + private BigDecimal amount; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/bean/User.java b/renren-admin/src/main/java/io/renren/modules/front/bean/User.java new file mode 100644 index 0000000..29bdd85 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/bean/User.java @@ -0,0 +1,91 @@ +package io.renren.modules.front.bean; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 用户信息(User)表实体类 + * + * @author 张宇轩 + * @since 2023-06-13 13:03:56 + */ +@Data +@NoArgsConstructor +@TableName("user") +public class User implements Serializable { + + /** + * id + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 姓名 + */ + private String name; + + /** + * 手机号 + */ + private String phone; + + /** + * 性别 0:男 1:女 2:保密 + */ + private Integer gender; + + /** + * 身份证号 + */ + private String idNumber; + + /** + * 头像 + */ + private String avatarUrl; + + /** + * 状态 0:禁用,1:正常 + */ + private Integer status; + + /** + * 微信openid + */ + private String openid; + + /** + * 微信昵称 + */ + private String nickName; + + /** + * 创建人 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createDate; + + /** + * 修改人 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/common/CustomException.java b/renren-admin/src/main/java/io/renren/modules/front/common/CustomException.java new file mode 100644 index 0000000..4a32f45 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/common/CustomException.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.common; + +/** + * @author : 张宇轩 + * @createTime : 2023/5/31 - 9:31 + */ +public class CustomException extends RuntimeException{ + public CustomException() { + super(); + } + + public CustomException(String message) { + super(message); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/common/GlobalExceptionHandler.java b/renren-admin/src/main/java/io/renren/modules/front/common/GlobalExceptionHandler.java new file mode 100644 index 0000000..2a11fbf --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/common/GlobalExceptionHandler.java @@ -0,0 +1,32 @@ +package io.renren.modules.front.common; + +import io.renren.modules.front.utils.R; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.sql.SQLIntegrityConstraintViolationException; + +/** + * @author : 张宇轩 + * @createTime : 2023/5/30 - 9:44 + */ +//全局异常处理 +@RestControllerAdvice(annotations = {RestController.class, Controller.class}) +public class GlobalExceptionHandler { + @ExceptionHandler(SQLIntegrityConstraintViolationException.class) + public R exceptionHandler(SQLIntegrityConstraintViolationException ex){ + String msg = ex.getMessage(); + String userName = ""; + if(msg.contains("Duplicate entry")){ + userName = msg.split(" ")[2]; + } + return R.error(userName + ":已经存在,无法注册!"); + } + + @ExceptionHandler(CustomException.class) + public R exceptionHandler(CustomException ex){ + return R.error(ex.getMessage()); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/common/JacksonObjectMapper.java b/renren-admin/src/main/java/io/renren/modules/front/common/JacksonObjectMapper.java new file mode 100644 index 0000000..02c0e0f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/common/JacksonObjectMapper.java @@ -0,0 +1,53 @@ +package io.renren.modules.front.common; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; + +import java.math.BigInteger; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; +/** + * @author : 张宇轩 + * @createTime : 2023/5/30 - 14:21 + * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象 + * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象] + * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON] + */ +public class JacksonObjectMapper extends ObjectMapper { + public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; + public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; + public JacksonObjectMapper() { + super(); + //收到未知属性时不报异常 + this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); + //反序列化时,属性不存在的兼容处理 + this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + SimpleModule simpleModule = new SimpleModule() + .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) + .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) + .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))) + + .addSerializer(BigInteger.class, ToStringSerializer.instance) + .addSerializer(Long.class, ToStringSerializer.instance) + + .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) + .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) + .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); + //注册功能模块 例如,可以添加自定义序列化器和反序列化器 + this.registerModule(simpleModule); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/front/config/AlipayConfig.java b/renren-admin/src/main/java/io/renren/modules/front/config/AlipayConfig.java new file mode 100644 index 0000000..5982eff --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/config/AlipayConfig.java @@ -0,0 +1,28 @@ +package io.renren.modules.front.config; + +/** + * @author : 张宇轩 + * @createTime : 2023/6/6 - 9:24 + */ +public class AlipayConfig { + // 商户appid + public static String APPID = "9021000122684341"; + // 私钥 pkcs8格式的 + public static String RSA_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHXI8YOl0FyS/72WUOy/Q0+cCju1pIVhgiSnyywKB9P1I+XcTgpMBpnHbwQsPaZUDdOkEdavwbFT+hTfS/np0oObyNvAbBjx5E60vSPntmO1lkwAO+U3sFk33IKUU2e/GxB7957+WWSOzXYAfpDQ43TKdwDHHE0ejXzVI67ERosRfvxfUb+2JC9069NkBgRAWkihnEyibWNXLXK4Bed2CgoKrPe7id/wxPqCoNxAkIRU092ta8NiK1gUpJBaZtC+slVWe/FHXHL5fZRsD25ojT9OUz5VhelN+cAGjfxnp1+K/XMBpqYfR1HWlJ6bD+JblIXsNOxkD6b7OIXtXOxHLlAgMBAAECggEAfVxcbezHb+9WkCFS9XQv88wF+90sjOenLELd39KED9rP+VBwYDhUtrqgcHz009OIUhp8aZlGaHKyXlpLPBfSpolqNb2YaDR6rQtZShpxwElgze0CyoaX3Z8uE20dW4tIWFK7o1tovllFd2XJja14qABG5X+w8b4RraLK8CUWafmKTJtHfHHib6kHSdedHEUemnz6zNpgfI1uA/HeiIeKcr81avB+7SHOgiXHePNfiIVpG2BcvXrUVVgHWxwGyaRYhrs/PsLWRATaVA5pFRUfd4x2IqfNQjzFMNbh+rz7NesJ00iy6w6xqJSwbT/2W+NRz3OleyD9AO56Z2NgMY7oQQKBgQD3R0mKIDLL9jAzjiOBczdJ69L42k+TOqOWW9Fagj30Vj3eICQvu/5g9x1M1EEWwsoA9JE9FjquBr4O2Ren9VqgxKVbZEPUVGxrd6XKv66HQ5tg7lj3hXw75nGWcy7RoRdIsQl1I+WEJykrFmxwXTM+LhY9wGCyEuvXDgf/dyHFMQKBgQCMIsIFEu78jvUcLPTP7JscN+AqqfvIl5WUN23TgGkjoiOQwOFEkp7OE1TH4SP+NDw44p+/m/zkAKqwpCLX9u0rinuhISlPXKO1ADcelRBuqteQJPHn1JiBPAaNwFu5gUc40bmdRnIPUr+N1n5LwG87eUdzXrdzXu6SB6ZBlaur9QKBgQDea9PdF0s5pO8EYJTVSpJvvlxdFNlA4BznER3FoKMjlTM/CoAiI6ITDBPh2IXXeEyFAXdmkAkmIdBwwJsDq7DiLR9jjlNouKtxGwUY0sOkzY4EaT/DHOF7a7O+FUsGqjSsYPnV0P0QmrzwEdJmW57NDl1ZHCKd6mESZn+RLVJF8QKBgDU4Kgj1RM+jlxCpPhwM1mdkDP0G6zkl4EeWuV3eYY+Hzwv1RFffevH2Q3dZWGr8+XX9EwAYxHTuj+RfoV/1ReMIR6VMy7x5CS7/Mu+pWsE8nnr+nOQXSAekfTSuPed4Yk0A0QYar8yD931tXS91mIi0qV72NKNbBS1uPESiC71VAoGAQ8hPlMDjkAoOl/rHbk3d7T+2xd0JyLD17zbzzC6iYdi/4e0tSBPM5Ua/IpxgACCOpCjCPsvVI37fN9RNrs/MWynQQ/4Ami6wuv9mB31U9lJU7mfjWDbiqPe6mGkiHjUkLN25B9+SVRRZ33+UnQzExVN4pVoMnt5Vr29xbkM9DfI="; + // 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 + public static String notify_url = "http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/notify_url.jsp"; + // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址 + public static String return_url = "http://localhost:8080/api/front/order/afterPayOrder"; + // 请求网关地址 + public static String URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do"; + // 编码 + public static String CHARSET = "UTF-8"; + // 返回格式 + public static String FORMAT = "json"; + // 支付宝公钥 + public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlofAiCXnSI1GzZP1TAD43+NJew4DmqJntECRj09BWFdkuIrjHuBysKdoCni10MweKnYj9L6IMF3DYBQvDv2PIuJPRIakFVlyOl542s9LgN3JFuEuenL00+7JOYuAJhi7LA6t3KtojOlu2w+GojwgmUoTyPc5x4be6q1X8bZEUESvf1SW+Wnqq3z8McwNM5twS4GA8J28NoIS20ovsR6Ba94Bo6/Z0XIDR9x0hWI2/vqOyrbJ4nh/X9no+vFQKCT2XZ3Htd9VxS8osnKddpQnXh+fM2ZcbbnjdV7cnkE84sCl9TA4TvjcQARNyL/GKIWheAz3F/28QX7QT+hexoqErQIDAQAB"; + // 日志记录目录定义在 logFile 中 + public static String log_path = "/log"; + // RSA2 + public static String SIGNTYPE = "RSA2"; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/AddressBookController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/AddressBookController.java new file mode 100644 index 0000000..248adeb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/AddressBookController.java @@ -0,0 +1,79 @@ +package io.renren.modules.front.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.renren.modules.front.bean.AddressBook; +import io.renren.modules.front.service.AddressBookService; +import io.renren.modules.front.utils.BaseContext; +import io.renren.modules.front.utils.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 地址管理(AddressBook)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "addressBookControllerFront") +@RequestMapping("front/addressBook") +public class AddressBookController { + /** + * 服务对象 + */ + @Autowired + private AddressBookService addressBookService; + + //查询当前登录用户的所有地址信息 + @GetMapping("/list") + public R> list(){ + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(AddressBook::getUserId, BaseContext.getCurrentId()); + List bookList = addressBookService.list(lqw); + return R.success(bookList); + } + + //添加收货地址 + @PostMapping + public R add(@RequestBody AddressBook addressBook){ + addressBook.setUserId(BaseContext.getCurrentId()); + addressBookService.save(addressBook); + return R.success("地址保存成功"); + } + + //设置默认地址 + @PutMapping("/default") + public R defaultAddress(@RequestBody AddressBook addressBook){ + addressBookService.defaultAddress(addressBook); + return R.success("设置默认地址成功!"); + } + + //查询默认地址 + @GetMapping("/default") + public R getDefaultAddress(){ + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(AddressBook::getUserId, BaseContext.getCurrentId()).eq(AddressBook::getIsDefault, 1); + return R.success(addressBookService.getOne(lqw)); + } + + //根据id获取地址信息 + @GetMapping("/{id}") + public R getAddressById(@PathVariable("id") Long id){ + AddressBook addressBook = addressBookService.getById(id); + return R.success(addressBook); + } + + //修改地址 + @PutMapping + public R updateAddress(@RequestBody AddressBook addressBook){ + addressBookService.updateById(addressBook); + return R.success("地址修改成功!"); + } + + @DeleteMapping + public R deleteAddress(@RequestParam("ids") Long ids){ + addressBookService.removeById(ids); + return R.success("地址删除成功"); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/AlipayController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/AlipayController.java new file mode 100644 index 0000000..cf75028 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/AlipayController.java @@ -0,0 +1,63 @@ +package io.renren.modules.front.controller; + +import com.alibaba.fastjson.JSONObject; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayClient; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.request.AlipayTradeWapPayRequest; +import com.alipay.api.response.AlipayTradeWapPayResponse; +import io.renren.modules.front.config.AlipayConfig; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.math.BigDecimal; + +/** + * @author : 张宇轩 + * @createTime : 2023/6/6 - 9:30 + */ +@RestController +@RequestMapping("front/pay") +@Slf4j +public class AlipayController { + //实现对接支付宝沙箱支付 + @GetMapping("/orderPay") + public String orderPay(@RequestParam("orderNum") Long out_trade_no, + @RequestParam("amount") BigDecimal total_amount) throws AlipayApiException { + AlipayClient alipayClient = new DefaultAlipayClient( + AlipayConfig.URL, + AlipayConfig.APPID, + AlipayConfig.RSA_PRIVATE_KEY, + AlipayConfig.FORMAT, + AlipayConfig.CHARSET, + AlipayConfig.ALIPAY_PUBLIC_KEY, + AlipayConfig.SIGNTYPE); + AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest(); + //异步接收地址,仅支持http/https,公网可访问 + request.setNotifyUrl(AlipayConfig.notify_url); + //同步跳转地址,仅支持http/https + request.setReturnUrl(AlipayConfig.return_url); + /* *****必传参数***** */ + JSONObject bizContent = new JSONObject(); + //商户订单号,商家自定义,保持唯一性 + bizContent.put("out_trade_no", out_trade_no); + //支付金额,最小值0.01元 + bizContent.put("total_amount", total_amount); + //订单标题,不可使用特殊符号 + bizContent.put("subject", "美食元素订单支付"); + + /* ****可选参数***** */ + //手机网站支付默认传值FAST_INSTANT_TRADE_PAY + bizContent.put("product_code", "QUICK_WAP_WAY"); + + request.setBizContent(bizContent.toString()); + AlipayTradeWapPayResponse response = alipayClient.pageExecute(request); + + String result = response.getBody(); + log.info("result: {}", result); + return result; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/CategoryController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/CategoryController.java new file mode 100644 index 0000000..12921df --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/CategoryController.java @@ -0,0 +1,68 @@ +package io.renren.modules.front.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.renren.modules.front.bean.Category; +import io.renren.modules.front.service.CategoryService; +import io.renren.modules.front.utils.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 菜品及套餐分类(Category)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "categoryControllerFront") +@RequestMapping("front/category") +public class CategoryController { + /** + * 服务对象 + */ + @Autowired + private CategoryService categoryService; + +// //添加菜品套餐的分类信息 +// @PostMapping +// public R add(@RequestBody Category category){ +// categoryService.save(category); +// return R.success("添加成功!"); +// } +// +// //分页查询员工信息 +// @GetMapping("/page") +// public R> page(@RequestParam Integer page, +// @RequestParam Integer pageSize){ +// IPage iPage = new Page<>(page, pageSize); +// QueryWrapper lqw = new QueryWrapper<>(); +// lqw.lambda().orderByDesc(Category::getUpdateDate); +// categoryService.page(iPage, lqw); +// return R.success(iPage); +// } +// +// @PutMapping +// public R update(@RequestBody Category category){ +// categoryService.updateById(category); +// return R.success("修改成功!"); +// } +// +// @DeleteMapping +// public R removeById(@RequestParam("id") Long cateId){ +// //删除分类信息 +// categoryService.removeCateById(cateId); +// return R.success("删除分类信息成功"); +// } + + @GetMapping("/list") + public R> list(@RequestParam(required = false) Integer type){ + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(type!=null, Category::getType, type).orderByDesc(Category::getUpdateDate); + List categoryList = categoryService.list(lqw); + return R.success(categoryList); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/DishController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/DishController.java new file mode 100644 index 0000000..15c6d4b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/DishController.java @@ -0,0 +1,186 @@ +package io.renren.modules.front.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.renren.modules.front.bean.Dish; +import io.renren.modules.front.bean.DishFlavor; +import io.renren.modules.front.dto.DishDTO; +import io.renren.modules.front.service.CategoryService; +import io.renren.modules.front.service.DishFlavorService; +import io.renren.modules.front.service.DishService; +import io.renren.modules.front.service.SetmealDishService; +import io.renren.modules.front.utils.R; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.util.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.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * 菜品管理(Dish)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "dishControllerFront") +@RequestMapping("front/dish") +public class DishController { + /** + * 服务对象 + */ + @Autowired + private DishService dishService; + + @Autowired + private CategoryService categoryService; + @Autowired + private SetmealDishService setmealDishService; + @Autowired + private DishFlavorService dishFlavorService; + + @Autowired + private RedisTemplate redisTemplate; + +// //保存菜品和口味信息 +// @PostMapping +// public R saveDishFlavor(@RequestBody DishDTO dishDTO){ +// dishService.saveDishFlavor(dishDTO); +// //清除当前分类下的菜品信息 +// redisTemplate.delete("dish_" + dishDTO.getCategoryId() + "_1"); +// return R.success("菜品保存成功!"); +// } +// +// //分页查询菜品信息 +// @GetMapping("/page") +// public R> page(@RequestParam Integer page, +// @RequestParam Integer pageSize, +// @RequestParam(required = false) String name){ +// //这个iPageDto才是最后封装返回的分页数据 +// Page iPageDto = new Page<>(page, pageSize); +// Page iPage = new Page<>(page, pageSize); +// LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.like(!StringUtils.isEmpty(name), Dish::getName, name).orderByDesc(Dish::getUpdateDate); +// dishService.page(iPage, lqw); +// //对象复制操作,把iPage中的分页数据(页数,总条数等)复制给iPageDto,具体的菜品数据不复制。 +// BeanUtils.copyProperties(iPage, iPageDto, "records"); +// //构建菜品数据,封装到PageDto中 +// List dishList = iPage.getRecords(); +// //把dishList转换为dishDtoList +// List dishDTOList = dishList.stream().map(dish -> { +// //构建新的DishDTO对象 +// DishDTO dishDTO = new DishDTO(); +// //把dish复制给dishDIO +// BeanUtils.copyProperties(dish, dishDTO); +// //获取categoryName,设置到DishDTo中 +// Category category = categoryService.getById(dish.getCategoryId()); +// dishDTO.setCategoryName( category.getName()); +// return dishDTO; +// }).collect(Collectors.toList()); +// //设置dishDTOList到iPageDto +// iPageDto.setRecords(dishDTOList); +// return R.success(iPageDto); +// } +// +// @PostMapping("/status/{status}") +// public R setStatus(@PathVariable("status") Integer status, +// @RequestParam List ids){ +// LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); +// luw.set(Dish::getStatus, status).set(Dish::getUpdateDate, LocalDateTime.now()).in(Dish::getId, ids); +// dishService.update(luw); +// return R.success("停售成功"); +// } +// +// @DeleteMapping +// public R delete(@RequestParam List ids){ +// LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); +// qw.in(Dish::getId, ids).eq(Dish::getStatus, 1); +// long cnt = dishService.count(qw); +// if(cnt > 0){ +// throw new CustomException("存在起售的菜品,不能删除"); +// } +// for (Long id : ids) { +// LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.eq(SetmealDish::getDishId, id); +// long count = setmealDishService.count(lqw); +// if (count > 0) { +// throw new CustomException("存在包含该菜品的套餐,无法删除"); +// } +// } +// for(Long id: ids) { +// LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); +// luw.eq(DishFlavor::getDishId, id); +// dishFlavorService.remove(luw); +// dishService.removeById(id); +// } +// //清除所有的菜品缓存数据 +// redisTemplate.delete("dish_*"); +// return R.success("删除成功"); +// } +// +// //根据菜品id查询菜品和口味的信息 +// @GetMapping("/{dishId}") +// public R getDIshFlavorById(@PathVariable("dishId") Long dishId){ +// DishDTO dishDTO = new DishDTO(); +// //查询菜品信息 +// Dish dish = dishService.getById(dishId); +// BeanUtils.copyProperties(dish, dishDTO); +// //查询当前菜品下的口味信息 +// LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.eq(DishFlavor::getDishId, dishId); +// List dishFlavorList = dishFlavorService.list(lqw); +// //把口味的集合放入DishDTO +// dishDTO.setFlavors(dishFlavorList); +// return R.success(dishDTO); +// } +// +// @PutMapping +// public R updateDishFlavor(@RequestBody DishDTO dishDTO){ +// //先查询当前菜品的分类id,清除当前分类的redis数据 +// Dish dish = dishService.getById(dishDTO.getId()); +// redisTemplate.delete("dish_" + dish.getCategoryId() + "_1"); +// //查询更新的菜品的分类id,清除更新的分类的redis数据 +// if(!dish.getCategoryId().equals(dishDTO.getCategoryId())){ +// redisTemplate.delete("dish_" + dishDTO.getCategoryId() + "_1"); +// } +// dishService.updateDishFlavor(dishDTO); +// return R.success("修改菜品信息成功"); +// } + + //根据分类的id,查询当前分类下的所有菜品信息 + @GetMapping("/list") + private R> list(Dish dish){ + //先从redis查询当前是否有分类下的菜品数据,如果有直接返回 + //string结构 + String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus(); + List dishDTOList = (List) redisTemplate.opsForValue().get(key); + //如果有,直接返回数据 + if(!CollectionUtils.isEmpty(dishDTOList)){ + return R.success(dishDTOList); + } + //如果没有,去mysql数据库查询 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(Dish::getCategoryId, dish.getCategoryId()) + //status为空时对应后台页面,非空则对应客户端页面 + .eq(dish.getStatus()!=null, Dish::getStatus, dish.getStatus()) + .orderByDesc(Dish::getSort).orderByDesc(Dish::getUpdateDate); + List dishList = dishService.list(lqw); + dishDTOList = dishList.stream().map(item -> { + DishDTO dishDTO = new DishDTO(); + BeanUtils.copyProperties(item, dishDTO); + //封装口味数据 + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(DishFlavor::getDishId, item.getId()); + List dishFlavorList = dishFlavorService.list(qw); + dishDTO.setFlavors(dishFlavorList); + return dishDTO; + }).collect(Collectors.toList()); + //把在msql查询的数据放入redis + redisTemplate.opsForValue().set(key, dishDTOList,1, TimeUnit.HOURS); + return R.success(dishDTOList); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/DishFlavorController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/DishFlavorController.java new file mode 100644 index 0000000..dacb40a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/DishFlavorController.java @@ -0,0 +1,24 @@ +package io.renren.modules.front.controller; + +import io.renren.modules.front.service.DishFlavorService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 菜品口味关系表(DishFlavor)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "dishFlavorControllerFront") +@RequestMapping("front/dishFlavor") +public class DishFlavorController { + /** + * 服务对象 + */ + @Autowired + private DishFlavorService dishFlavorService; + + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/OrderDetailController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/OrderDetailController.java new file mode 100644 index 0000000..24881eb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/OrderDetailController.java @@ -0,0 +1,24 @@ +package io.renren.modules.front.controller; + +import io.renren.modules.front.service.OrderDetailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 订单明细表(OrderDetail)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "orderDetailControllerFront") +@RequestMapping("front/orderDetail") +public class OrderDetailController { + /** + * 服务对象 + */ + @Autowired + private OrderDetailService orderDetailService; + + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/OrdersController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/OrdersController.java new file mode 100644 index 0000000..80250fa --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/OrdersController.java @@ -0,0 +1,88 @@ +package io.renren.modules.front.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.renren.modules.front.bean.Orders; +import io.renren.modules.front.dto.OrdersDTO; +import io.renren.modules.front.service.OrdersService; +import io.renren.modules.front.utils.BaseContext; +import io.renren.modules.front.utils.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDateTime; + +/** + * 订单表(Orders)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@Controller(value = "ordersControllerFront") +@RequestMapping("front/order") +public class OrdersController { + /** + * 服务对象 + */ + @Autowired + private OrdersService ordersService; + +// @GetMapping("/page") +// @ResponseBody +// public R> page(@RequestParam Integer page, +// @RequestParam Integer pageSize, +// @RequestParam(required = false) String number, +// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") +// @RequestParam(required = false) LocalDateTime beginTime, +// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") +// @RequestParam(required = false) LocalDateTime endTime){ +// Page ordersPage = new Page<>(page, pageSize); +// LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.like(number!=null, Orders::getNumber, number) +// .ge(beginTime!=null, Orders::getOrderTime, beginTime) +// .le(endTime!=null, Orders::getOrderTime, endTime); +// ordersService.page(ordersPage, lqw); +// return R.success(ordersPage); +// } +// +// @PutMapping +// @ResponseBody +// public R setStatus(@RequestBody Orders orders){ +// LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); +// luw.eq(Orders::getId, orders.getId()).set(Orders::getStatus, orders.getStatus()); +// ordersService.update(luw); +// return R.success("状态更改成功!"); +// } + + //下单操作 + @PostMapping("/submit") + @ResponseBody + public R addOrder(@RequestBody Orders orders){ + Orders order = ordersService.addOrder(orders); + return R.success(order); + } + + //查看订单 + @GetMapping("/userPage") + @ResponseBody + public R> page(@RequestParam Integer page, + @RequestParam Integer pageSize){ + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(Orders::getUserId, BaseContext.getCurrentId()).orderByDesc(Orders::getOrderTime); + Page dtoPage = ordersService.getUserPage(page, pageSize, lqw); + return R.success(dtoPage); + } + + //支付完成之后的回调方法,处理订单状态等 + @GetMapping("/afterPayOrder") + public String afterPayOrder(@RequestParam String out_trade_no){ + LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); + luw.eq(Orders::getNumber, out_trade_no) + .set(Orders::getStatus, 2) + .set(Orders::getCheckoutTime, LocalDateTime.now()); + ordersService.update(luw); + return "redirect:http://localhost:8001/front/page/pay-success.html"; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/SetmealController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/SetmealController.java new file mode 100644 index 0000000..df033e7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/SetmealController.java @@ -0,0 +1,147 @@ +package io.renren.modules.front.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.renren.modules.front.bean.Dish; +import io.renren.modules.front.bean.Setmeal; +import io.renren.modules.front.bean.SetmealDish; +import io.renren.modules.front.dto.SetmealDishDTO; +import io.renren.modules.front.service.CategoryService; +import io.renren.modules.front.service.DishService; +import io.renren.modules.front.service.SetmealDishService; +import io.renren.modules.front.service.SetmealService; +import io.renren.modules.front.utils.R; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +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.stream.Collectors; + +/** + * 套餐(Setmeal)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "setmealControllerFront") +@RequestMapping("front/setmeal") +public class SetmealController { + /** + * 服务对象 + */ + @Autowired + private SetmealService setmealService; + @Autowired + private CategoryService categoryService; + @Autowired + private SetmealDishService setmealDishService; + @Autowired + private DishService dishService; + +// //添加套餐信息 +// @CacheEvict(value = "setmealCache", allEntries = true) +// @PostMapping +// public R saveSetmealDish(@RequestBody SetmealDTO setmealDTO){ +// setmealService.saveSetmealDish(setmealDTO); +// return R.success("套餐添加成功!"); +// } +// +// @GetMapping("/page") +// public R> page(@RequestParam Integer page, +// @RequestParam Integer pageSize, +// @RequestParam(required = false) String name){ +// IPage setmealDTOIPage = new Page<>(); +// IPage iPage = new Page<>(page, pageSize); +// LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.like(!StringUtils.isEmpty(name), Setmeal::getName, name); +// setmealService.page(iPage, lqw); +// BeanUtils.copyProperties(iPage, setmealDTOIPage, "records"); +// List setmealDTOList = iPage.getRecords().stream().map(setmeal -> { +// SetmealDTO setmealDTO = new SetmealDTO(); +// BeanUtils.copyProperties(setmeal, setmealDTO); +// Category category = categoryService.getById(setmeal.getCategoryId()); +// setmealDTO.setCategoryName(category.getName()); +// return setmealDTO; +// }).collect(Collectors.toList()); +// setmealDTOIPage.setRecords(setmealDTOList); +// return R.success(setmealDTOIPage); +// } +// +// @PostMapping("/status/{status}") +// public R setStatus(@PathVariable("status") Integer status, +// @RequestParam List ids){ +// LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); +// luw.set(Setmeal::getStatus, status).set(Setmeal::getUpdateDate, LocalDateTime.now()).in(Setmeal::getId, ids); +// setmealService.update(luw); +// return R.success("停售成功"); +// } +// +// @DeleteMapping +// public R delete(@RequestParam List ids){ +// LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); +// qw.in(Setmeal::getId, ids).eq(Setmeal::getStatus, 1); +// long cnt = setmealService.count(qw); +// if(cnt > 0){ +// throw new CustomException("存在起售的套餐,不能删除"); +// } +// for (Long id : ids) { +// LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); +// luw.eq(SetmealDish::getSetmealId, id); +// setmealDishService.remove(luw); +// } +// setmealService.removeBatchByIds(ids); +// return R.success("删除成功"); +// } +// +// @GetMapping("/{setmealId}") +// public R getSetmealById(@PathVariable("setmealId") Long setmealId){ +// Setmeal setmeal = setmealService.getById(setmealId); +// SetmealDTO setmealDTO = new SetmealDTO(); +// BeanUtils.copyProperties(setmeal, setmealDTO); +// +// LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.eq(SetmealDish::getSetmealId, setmealId); +// List setmealDishList = setmealDishService.list(lqw); +// setmealDTO.setSetmealDishes(setmealDishList); +// return R.success(setmealDTO); +// } +// +// @PutMapping +// public R update(@RequestBody SetmealDTO setmealDTO){ +// setmealService.updateSetmealDish(setmealDTO); +// return R.success("套餐保存成功!"); +// } + + //根据分类id和状态查询套餐信息 + @GetMapping("/list") + @Cacheable(value = "setmealCache", key = "#setmeal.categoryId + '_' + #setmeal.status") + public R> list(Setmeal setmeal){ + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(Setmeal::getCategoryId, setmeal.getCategoryId()) + .eq(setmeal.getStatus()!=null, Setmeal::getStatus, setmeal.getStatus()) + .orderByDesc(Setmeal::getUpdateDate); + List setmealList = setmealService.list(lqw); + return R.success(setmealList); + } + + //查看套餐详情 + @GetMapping("/dish/{id}") + public R> getSetmealDetail(@PathVariable("id") Long id){ + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(SetmealDish::getSetmealId, id).orderByDesc(SetmealDish::getUpdateDate); + List setmealDishList = setmealDishService.list(lqw); + + List list = setmealDishList.stream().map(setmealDish -> { + SetmealDishDTO setmealDishDTO = new SetmealDishDTO(); + BeanUtils.copyProperties(setmealDish, setmealDishDTO); + Dish dish = dishService.getById(setmealDish.getDishId()); + setmealDishDTO.setImage(dish.getImage()); + return setmealDishDTO; + }).collect(Collectors.toList()); + return R.success(list); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/SetmealDishController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/SetmealDishController.java new file mode 100644 index 0000000..d51ae01 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/SetmealDishController.java @@ -0,0 +1,43 @@ +package io.renren.modules.front.controller; + +import io.renren.modules.front.service.DishService; +import io.renren.modules.front.service.SetmealDishService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 套餐菜品关系(SetmealDish)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "setmealDishControllerFront") +@RequestMapping("front/setmealDish") +public class SetmealDishController { + /** + * 服务对象 + */ + @Autowired + private SetmealDishService setmealDishService; + @Autowired + private DishService dishService; + +// //查询套餐详情信息 +// @GetMapping("/dish/{id}") +// public R> setmealDetail(@PathVariable Long id) { +// LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); +// lqw.eq(SetmealDish::getSetmealId, id) +// .orderByDesc(SetmealDish::getUpdateDate); +// List setmealDishList = setmealDishService.list(lqw); +// List setmealDishDTOList = setmealDishList.stream().map(setmealDish -> { +// SetmealDishDTO setmealDishDTO = new SetmealDishDTO(); +// BeanUtils.copyProperties(setmealDish, setmealDishDTO); +// Dish dish = dishService.getById(setmealDish.getDishId()); +// setmealDishDTO.setImage(dish.getImage()); +// return setmealDishDTO; +// }).collect(Collectors.toList()); +// return R.success(setmealDishDTOList); +// } + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/ShoppingCartController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/ShoppingCartController.java new file mode 100644 index 0000000..0e02c12 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/ShoppingCartController.java @@ -0,0 +1,59 @@ +package io.renren.modules.front.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import io.renren.modules.front.bean.ShoppingCart; +import io.renren.modules.front.service.ShoppingCartService; +import io.renren.modules.front.utils.BaseContext; +import io.renren.modules.front.utils.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 购物车(ShoppingCart)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "shoppingCartControllerFront") +@RequestMapping("front/shoppingCart") +public class ShoppingCartController { + /** + * 服务对象 + */ + @Autowired + private ShoppingCartService shoppingCartService; + + @GetMapping("/list") + public R> list(){ + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(ShoppingCart::getUserId, BaseContext.getCurrentId()); + return R.success(shoppingCartService.list(lqw)); + } + + //添加购物车 + @PostMapping("/add") + public R add(@RequestBody ShoppingCart shoppingCart){ + ShoppingCart cart = shoppingCartService.add(shoppingCart); + return R.success(cart); + } + + //减少菜品/套餐数量 + @PostMapping("/sub") + public R sub(@RequestBody ShoppingCart cart){ + ShoppingCart shoppingCart = shoppingCartService.sub(cart); + return R.success(shoppingCart); + } + + //清空购物车 + @DeleteMapping("/clean") + public R clean(){ + LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); + luw.eq(ShoppingCart::getUserId, BaseContext.getCurrentId()); + shoppingCartService.remove(luw); + return R.success("购物车清空成功"); + } + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/controller/UserController.java b/renren-admin/src/main/java/io/renren/modules/front/controller/UserController.java new file mode 100644 index 0000000..a602b55 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/controller/UserController.java @@ -0,0 +1,114 @@ +package io.renren.modules.front.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.renren.modules.front.bean.User; +import io.renren.modules.front.service.UserService; +import io.renren.modules.front.utils.BaseContext; +import io.renren.modules.front.utils.R; +import io.renren.modules.front.utils.SendEmailUtils; +import io.renren.modules.front.utils.ValidateCodeUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.mail.EmailException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 用户信息(User)表控制层 + * + * @author 张宇轩 + * @since 2023-05-29 11:09:40 + */ +@RestController(value = "userControllerFront") +@RequestMapping("front/user") +@Slf4j +public class UserController { + /** + * 服务对象 + */ + @Autowired + private UserService userService; + + @Autowired + private RedisTemplate redisTemplate; + + //发送验证码 + @PostMapping("/sendMsg") + public R sendMsg(@RequestBody User user, HttpSession session){ + //生成6位随机数字验证码 + String code = ValidateCodeUtils.generateValidateCode(6).toString(); + log.info("验证码:{}", code); + //发送短信,让用户接受验证码 + try { + SendEmailUtils.sendAuthCodeEmail(user.getPhone(), code); + //把验证码保存到redis,1分钟有效 + redisTemplate.opsForValue().set(user.getPhone() + ":code", code, 1, TimeUnit.MINUTES); + return R.success("验证码发送成功"); + } catch (EmailException e) { + e.printStackTrace(); + return R.error("验证码发送失败"); + } + } + + //用户登录 + @PostMapping("/login") + public R login(HttpSession session, @RequestBody Map map, HttpServletResponse response){ + //获取前端传递的数据 + String phone = (String) map.get("phone"); + String code = (String) map.get("code"); + //将前端传来的code与redis中的code比较 + Object redisCode = redisTemplate.opsForValue().get(phone + ":code"); + if(redisCode == null){ + return R.error("验证码过期,请重新发送验证码"); + } + if(code!=null && code.equals(redisCode)){ + //根据手机号查询用户信息 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(User::getPhone, phone); + User user = userService.getOne(lqw); + if (user == null) { + //用户不存在,注册用户信息 + user = new User(); + user.setPhone(phone); + user.setStatus(1); + userService.save(user); + } + //将用户id存到session中 +// session.setAttribute("user", user.getId()); + Cookie cookie = new Cookie("user", String.valueOf(user.getId())); + cookie.setPath("/"); + cookie.setDomain("localhost"); + cookie.setHttpOnly(true); + + response.addCookie(cookie); + System.out.println("cookie['user'] = " + cookie.getValue()); + //验证码使用之后,从redis中删除 + redisTemplate.delete(phone + ":code"); + return R.success("用户登录成功"); + } + return R.error("验证码错误"); + } + + //用户登出 + @PostMapping("/loginout") + public R logout(HttpServletResponse response){ + BaseContext.setCurrentId(null); + Cookie cookie = new Cookie("user", null); + cookie.setPath("/"); + cookie.setDomain("localhost"); + cookie.setHttpOnly(true); + cookie.setMaxAge(0); + + response.addCookie(cookie); + return R.success("退出成功"); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/AddressBookMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/AddressBookMapper.java new file mode 100644 index 0000000..c7ec0a2 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/AddressBookMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.AddressBook; +import org.apache.ibatis.annotations.Mapper; + +/** + * 地址管理(AddressBook)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:43 + */ +@Mapper +public interface AddressBookMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/CategoryMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/CategoryMapper.java new file mode 100644 index 0000000..d50b8ef --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/CategoryMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.Category; +import org.apache.ibatis.annotations.Mapper; + +/** + * 菜品及套餐分类(Category)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:43 + */ +@Mapper +public interface CategoryMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/DishFlavorMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/DishFlavorMapper.java new file mode 100644 index 0000000..c62b99c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/DishFlavorMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.DishFlavor; +import org.apache.ibatis.annotations.Mapper; + +/** + * 菜品口味关系表(DishFlavor)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +@Mapper +public interface DishFlavorMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/DishMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/DishMapper.java new file mode 100644 index 0000000..409397a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/DishMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.Dish; +import org.apache.ibatis.annotations.Mapper; + +/** + * 菜品管理(Dish)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +@Mapper +public interface DishMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/OrderDetailMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/OrderDetailMapper.java new file mode 100644 index 0000000..23b78e3 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/OrderDetailMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.OrderDetail; +import org.apache.ibatis.annotations.Mapper; + +/** + * 订单明细表(OrderDetail)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +@Mapper +public interface OrderDetailMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/OrdersMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/OrdersMapper.java new file mode 100644 index 0000000..97f9396 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/OrdersMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.Orders; +import org.apache.ibatis.annotations.Mapper; + +/** + * 订单表(Orders)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Mapper +public interface OrdersMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/SetmealDishMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/SetmealDishMapper.java new file mode 100644 index 0000000..38ac07e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/SetmealDishMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.SetmealDish; +import org.apache.ibatis.annotations.Mapper; + +/** + * 套餐菜品关系(SetmealDish)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Mapper +public interface SetmealDishMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/SetmealMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/SetmealMapper.java new file mode 100644 index 0000000..1d2ed73 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/SetmealMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.Setmeal; +import org.apache.ibatis.annotations.Mapper; + +/** + * 套餐(Setmeal)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Mapper +public interface SetmealMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/ShoppingCartMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/ShoppingCartMapper.java new file mode 100644 index 0000000..22c7520 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/ShoppingCartMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.ShoppingCart; +import org.apache.ibatis.annotations.Mapper; + +/** + * 购物车(ShoppingCart)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Mapper +public interface ShoppingCartMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dao/UserMapper.java b/renren-admin/src/main/java/io/renren/modules/front/dao/UserMapper.java new file mode 100644 index 0000000..9b757a0 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dao/UserMapper.java @@ -0,0 +1,15 @@ +package io.renren.modules.front.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.front.bean.User; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户信息(User)表数据库访问层 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:46 + */ +@Mapper +public interface UserMapper extends BaseMapper { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dto/DishDTO.java b/renren-admin/src/main/java/io/renren/modules/front/dto/DishDTO.java new file mode 100644 index 0000000..45d1e33 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dto/DishDTO.java @@ -0,0 +1,24 @@ +package io.renren.modules.front.dto; + +import io.renren.modules.front.bean.Dish; +import io.renren.modules.front.bean.DishFlavor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * @author : 张宇轩 + * @createTime : 2023/5/31 - 14:30 + */ +@Data +@NoArgsConstructor +public class DishDTO extends Dish implements Serializable { + //口味的集合 + private List flavors = new ArrayList<>(); + + //分类的名称 与前端elementUI的prop属性一致 + private String categoryName; +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dto/OrdersDTO.java b/renren-admin/src/main/java/io/renren/modules/front/dto/OrdersDTO.java new file mode 100644 index 0000000..4cbf9cb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dto/OrdersDTO.java @@ -0,0 +1,19 @@ +package io.renren.modules.front.dto; + +import io.renren.modules.front.bean.OrderDetail; +import io.renren.modules.front.bean.Orders; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * @author : 张宇轩 + * @createTime : 2023/6/5 - 16:15 + */ +@Data +@NoArgsConstructor +public class OrdersDTO extends Orders implements Serializable { + private List orderDetails; +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDTO.java b/renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDTO.java new file mode 100644 index 0000000..d908ec5 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDTO.java @@ -0,0 +1,22 @@ +package io.renren.modules.front.dto; + +import io.renren.modules.front.bean.Setmeal; +import io.renren.modules.front.bean.SetmealDish; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * @author : 张宇轩 + * @createTime : 2023/6/1 - 11:17 + */ +@Data +@NoArgsConstructor +public class SetmealDTO extends Setmeal implements Serializable { + private List setmealDishes = new ArrayList<>(); + + private String categoryName; +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDishDTO.java b/renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDishDTO.java new file mode 100644 index 0000000..3965cf3 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/dto/SetmealDishDTO.java @@ -0,0 +1,17 @@ +package io.renren.modules.front.dto; + +import io.renren.modules.front.bean.SetmealDish; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author : 张宇轩 + * @createTime : 2023/6/2 - 15:54 + */ +@Data +@NoArgsConstructor +public class SetmealDishDTO extends SetmealDish implements Serializable { + private String image; +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/interceptor/LoginFilter.java b/renren-admin/src/main/java/io/renren/modules/front/interceptor/LoginFilter.java new file mode 100644 index 0000000..b752b6b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/interceptor/LoginFilter.java @@ -0,0 +1,82 @@ +package io.renren.modules.front.interceptor; + +import com.alibaba.fastjson.JSONObject; +import io.renren.modules.front.utils.BaseContext; +import io.renren.modules.front.utils.R; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.StringUtils; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; + +/** + * @author : 张宇轩 + * @createTime : 2023/6/13 - 20:09 + */ +@Slf4j +@Component +public class LoginFilter extends BasicHttpAuthenticationFilter { + //请求到达控制器之前拦截 + @Override + public boolean preHandle(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + //设置允许跨域 + response.setContentType("application/json;charset=UTF-8"); + String origin = request.getHeader("Origin"); + if (StringUtils.hasText(origin)){ + response.setHeader("Access-Control-Allow-Origin", origin); + } + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); + response.setHeader("Access-Control-Allow-Headers", "Content-Type,token"); + + //获取当前线程id + long id = Thread.currentThread().getId(); + log.info("LoginFilter >> 线程Id: {}, RequestURI: {}", id, request.getRequestURI()); + //2.检测是否为前台页面请求 + if(new AntPathMatcher().match("/api/front/**", request.getRequestURI())){ + + //是登录相关请求,直接放行 + if(new AntPathMatcher().match("/api/front/user/**", request.getRequestURI())){ + log.info("LoginFilter >> "+request.getRequestURI()+">> 与/api/front/user/**匹配"); + return true; + } + //其他前台请求 + log.info("LoginFilter >> "+request.getRequestURI()+">> 与/api/front/**匹配"); + //获取cookie['user'] + String userObj = null; + Cookie[] cookies = request.getCookies(); + log.info(Arrays.toString(cookies)); + if (cookies != null) { + for (Cookie cookie : cookies) { + if ("user".equals(cookie.getName())) { + userObj = cookie.getValue(); + } + } + } + log.info("LoginFilter >> "+request.getRequestURI()+" >> cookie['user'] = " + userObj); + //判断是否为空 + if (userObj != null) { + log.info("当前用户已经登录,用户id为:{}", userObj); + //把userId放入ThreadLocal中 + BaseContext.setCurrentId(Long.valueOf(userObj)); + return true; + } + //未登录,响应数据 + response.getWriter().write(JSONObject.toJSONString(R.error("NOTLOGIN"))); + return false; + } + + log.info("LoginFilter >> 后台页面请求"); + return true; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/AddressBookService.java b/renren-admin/src/main/java/io/renren/modules/front/service/AddressBookService.java new file mode 100644 index 0000000..310cd9d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/AddressBookService.java @@ -0,0 +1,14 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.AddressBook; + +/** + * 地址管理(AddressBook)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:43 + */ +public interface AddressBookService extends IService { + void defaultAddress(AddressBook addressBook); +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/CategoryService.java b/renren-admin/src/main/java/io/renren/modules/front/service/CategoryService.java new file mode 100644 index 0000000..7c05651 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/CategoryService.java @@ -0,0 +1,14 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.Category; + +/** + * 菜品及套餐分类(Category)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +public interface CategoryService extends IService { + void removeCateById(Long cateId); +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/DishFlavorService.java b/renren-admin/src/main/java/io/renren/modules/front/service/DishFlavorService.java new file mode 100644 index 0000000..9c8d9f0 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/DishFlavorService.java @@ -0,0 +1,13 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.DishFlavor; + +/** + * 菜品口味关系表(DishFlavor)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +public interface DishFlavorService extends IService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/DishService.java b/renren-admin/src/main/java/io/renren/modules/front/service/DishService.java new file mode 100644 index 0000000..b7ad566 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/DishService.java @@ -0,0 +1,17 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.Dish; +import io.renren.modules.front.dto.DishDTO; + +/** + * 菜品管理(Dish)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +public interface DishService extends IService { + void saveDishFlavor(DishDTO dishDTO); + + void updateDishFlavor(DishDTO dishDTO); +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/OrderDetailService.java b/renren-admin/src/main/java/io/renren/modules/front/service/OrderDetailService.java new file mode 100644 index 0000000..f9bd78b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/OrderDetailService.java @@ -0,0 +1,13 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.OrderDetail; + +/** + * 订单明细表(OrderDetail)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +public interface OrderDetailService extends IService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/OrdersService.java b/renren-admin/src/main/java/io/renren/modules/front/service/OrdersService.java new file mode 100644 index 0000000..3976cc6 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/OrdersService.java @@ -0,0 +1,19 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.Orders; +import io.renren.modules.front.dto.OrdersDTO; + +/** + * 订单表(Orders)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +public interface OrdersService extends IService { + Orders addOrder(Orders orders); + + Page getUserPage(Integer page, Integer pageSize, LambdaQueryWrapper lqw); +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/SetmealDishService.java b/renren-admin/src/main/java/io/renren/modules/front/service/SetmealDishService.java new file mode 100644 index 0000000..aac3145 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/SetmealDishService.java @@ -0,0 +1,13 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.SetmealDish; + +/** + * 套餐菜品关系(SetmealDish)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +public interface SetmealDishService extends IService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/SetmealService.java b/renren-admin/src/main/java/io/renren/modules/front/service/SetmealService.java new file mode 100644 index 0000000..2b30df6 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/SetmealService.java @@ -0,0 +1,16 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.Setmeal; + +/** + * 套餐(Setmeal)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +public interface SetmealService extends IService { +// void saveSetmealDish(SetmealDTO setmealDTO); +// +// void updateSetmealDish(SetmealDTO setmealDTO); +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/ShoppingCartService.java b/renren-admin/src/main/java/io/renren/modules/front/service/ShoppingCartService.java new file mode 100644 index 0000000..caecc8f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/ShoppingCartService.java @@ -0,0 +1,16 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.ShoppingCart; + +/** + * 购物车(ShoppingCart)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +public interface ShoppingCartService extends IService { + ShoppingCart add(ShoppingCart shoppingCart); + + ShoppingCart sub(ShoppingCart cart); +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/UserService.java b/renren-admin/src/main/java/io/renren/modules/front/service/UserService.java new file mode 100644 index 0000000..d1a9c59 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/UserService.java @@ -0,0 +1,13 @@ +package io.renren.modules.front.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.front.bean.User; + +/** + * 用户信息(User)表服务接口 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:46 + */ +public interface UserService extends IService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/AddressBookServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/AddressBookServiceImpl.java new file mode 100644 index 0000000..cb665c1 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/AddressBookServiceImpl.java @@ -0,0 +1,32 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.AddressBook; +import io.renren.modules.front.dao.AddressBookMapper; +import io.renren.modules.front.service.AddressBookService; +import io.renren.modules.front.utils.BaseContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 地址管理(AddressBook)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:43 + */ +@Service(value = "addressBookServiceImplFront") +@Transactional +public class AddressBookServiceImpl extends ServiceImpl implements AddressBookService { + @Override + public void defaultAddress(AddressBook addressBook) { + //把当前登录用户的所有地址的默认值改为0 + LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); + luw.eq(AddressBook::getUserId, BaseContext.getCurrentId()).set(AddressBook::getIsDefault, 0); + this.update(luw); + //把当前登录用户的当前地址的默认值改为1 + LambdaUpdateWrapper luw1 = new LambdaUpdateWrapper<>(); + luw1.eq(AddressBook::getId, addressBook.getId()).set(AddressBook::getIsDefault, 1); + this.update(luw1); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/CategoryServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/CategoryServiceImpl.java new file mode 100644 index 0000000..3ba5fb7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/CategoryServiceImpl.java @@ -0,0 +1,51 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.Category; +import io.renren.modules.front.bean.Dish; +import io.renren.modules.front.bean.Setmeal; +import io.renren.modules.front.common.CustomException; +import io.renren.modules.front.dao.CategoryMapper; +import io.renren.modules.front.service.CategoryService; +import io.renren.modules.front.service.DishService; +import io.renren.modules.front.service.SetmealService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 菜品及套餐分类(Category)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +@Service(value = "categoryServiceImplFront") +@Transactional +public class CategoryServiceImpl extends ServiceImpl implements CategoryService { + + @Autowired + private DishService dishService; + @Autowired + private SetmealService setmealService; + + @Override + public void removeCateById(Long cateId) { + //判断当前分类下,是否有菜品信息,如果有则不能删除 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(Dish::getCategoryId, cateId); + long dishCount = dishService.count(lqw); + if (dishCount > 0) { + throw new CustomException("当前分类下有菜品信息,不能删除!"); + } + //判断当前分类下,是否有套餐信息,如果有则不能删除 + LambdaQueryWrapper lqw1 = new LambdaQueryWrapper<>(); + lqw1.eq(Setmeal::getCategoryId, cateId); + long setmealCount = setmealService.count(lqw1); + if(setmealCount > 0){ + throw new CustomException("当前分类下有套餐信息,不能删除!"); + } + //删除当前分类信息 + this.removeById(cateId); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/DishFlavorServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/DishFlavorServiceImpl.java new file mode 100644 index 0000000..c0f3dee --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/DishFlavorServiceImpl.java @@ -0,0 +1,19 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.DishFlavor; +import io.renren.modules.front.dao.DishFlavorMapper; +import io.renren.modules.front.service.DishFlavorService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 菜品口味关系表(DishFlavor)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +@Service(value = "dishFlavorServiceImplFront") +@Transactional +public class DishFlavorServiceImpl extends ServiceImpl implements DishFlavorService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/DishServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/DishServiceImpl.java new file mode 100644 index 0000000..f572d0a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/DishServiceImpl.java @@ -0,0 +1,58 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.Dish; +import io.renren.modules.front.bean.DishFlavor; +import io.renren.modules.front.dao.DishMapper; +import io.renren.modules.front.dto.DishDTO; +import io.renren.modules.front.service.DishFlavorService; +import io.renren.modules.front.service.DishService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 菜品管理(Dish)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +@Service(value = "dishServiceImplFront") +@Transactional +public class DishServiceImpl extends ServiceImpl implements DishService { + @Autowired + private DishFlavorService dishFlavorService; + + @Override + public void saveDishFlavor(DishDTO dishDTO) { + //封装菜品信息,保存 + this.save(dishDTO); + //封装口味信息 + List flavorList = dishDTO.getFlavors().stream().map(dishFlavor -> { + dishFlavor.setDishId(dishDTO.getId()); + return dishFlavor; + }).collect(Collectors.toList()); + //批量保存数据 + dishFlavorService.saveBatch(flavorList); + } + + @Override + public void updateDishFlavor(DishDTO dishDTO){ + //保存修改的菜品信息 + this.updateById(dishDTO); + //删除旧口味数据 + LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); + luw.eq(DishFlavor::getDishId, dishDTO.getId()); + dishFlavorService.remove(luw); + //保存新口味 + List flavorList = dishDTO.getFlavors().stream().map(dishFlavor -> { + dishFlavor.setDishId(dishDTO.getId()); + return dishFlavor; + }).collect(Collectors.toList()); + dishFlavorService.saveBatch(flavorList); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/OrderDetailServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/OrderDetailServiceImpl.java new file mode 100644 index 0000000..a73274b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/OrderDetailServiceImpl.java @@ -0,0 +1,17 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.OrderDetail; +import io.renren.modules.front.dao.OrderDetailMapper; +import io.renren.modules.front.service.OrderDetailService; +import org.springframework.stereotype.Service; + +/** + * 订单明细表(OrderDetail)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:44 + */ +@Service(value = "orderDetailServiceImplFront") +public class OrderDetailServiceImpl extends ServiceImpl implements OrderDetailService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/OrdersServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/OrdersServiceImpl.java new file mode 100644 index 0000000..2f3d09d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/OrdersServiceImpl.java @@ -0,0 +1,115 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.*; +import io.renren.modules.front.common.CustomException; +import io.renren.modules.front.dao.OrdersMapper; +import io.renren.modules.front.dto.OrdersDTO; +import io.renren.modules.front.service.*; +import io.renren.modules.front.utils.BaseContext; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + * 订单表(Orders)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Service(value = "ordersServiceImplFront") +public class OrdersServiceImpl extends ServiceImpl implements OrdersService { + + @Autowired + private UserService userService; + @Autowired + private AddressBookService addressBookService; + @Autowired + private ShoppingCartService shoppingCartService; + @Autowired + private OrderDetailService orderDetailService; + + @Override + public Orders addOrder(Orders orders) { + //1.查询用户信息 + User user = userService.getById(BaseContext.getCurrentId()); + //2.查询地址信息 + AddressBook addressBook = addressBookService.getById(orders.getAddressBookId()); + //3.保存订单明细的数据 + //3-1.生成订单id + long orderId = IdWorker.getId(); + //3-2.查询购物车数据 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(ShoppingCart::getUserId, BaseContext.getCurrentId()); + List shoppingCartList = shoppingCartService.list(lqw); + if (CollectionUtils.isEmpty(shoppingCartList)) { + throw new CustomException("当前购物车信息为空,无法下单"); + } + //3-3.计算总金额-考虑多线程并发安全的问题 + //AtomInteger:提供了原子性的计算操作 + AtomicInteger amount = new AtomicInteger(); + //3-4.遍历购物车集合,构建订单明细数据 + List orderDetailList = shoppingCartList.stream().map(cart -> { + //总金额 += 数量*单价 + amount.addAndGet(cart.getAmount() + .multiply(new BigDecimal(cart.getNumber())).intValue()); + OrderDetail orderDetail = new OrderDetail(); + orderDetail.setOrderId(orderId); + BeanUtils.copyProperties(cart, orderDetail); + return orderDetail; + }).collect(Collectors.toList()); + //4.封装订单表的数据 + Orders order = new Orders(); + order.setNumber(String.valueOf(orderId)); + order.setStatus(1); + order.setUserId(user.getId()); + order.setAddressBookId(orders.getAddressBookId()); + order.setOrderTime(LocalDateTime.now()); + order.setPayMethod(2); + order.setAmount(new BigDecimal(amount.get())); + order.setRemark(orders.getRemark()); + order.setPhone(addressBook.getPhone()); + order.setAddress(addressBook.getDetail()); + order.setUserName(user.getName()); + order.setConsignee(addressBook.getConsignee()); + //5.保存订单数据 + this.save(order); + //6.保存订单明细苏剧 + orderDetailService.saveBatch(orderDetailList); + //7.清空购物车数据 + shoppingCartService.remove(lqw); + return order; + } + + @Override + public Page getUserPage(Integer page, Integer pageSize, LambdaQueryWrapper lqw) { + Page ordersPage = this.page(new Page<>(page, pageSize), lqw); + List dtoList = ordersPage.getRecords().stream().map(orders -> { + OrdersDTO ordersDTO = new OrdersDTO(); + LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); + qw.eq(OrderDetail::getOrderId, orders.getNumber()); + List detailList = orderDetailService.list(qw); + + BeanUtils.copyProperties(orders, ordersDTO); + ordersDTO.setOrderDetails(detailList); + return ordersDTO; + }).collect(Collectors.toList()); + + Page dtoPage = new Page<>(); + BeanUtils.copyProperties(ordersPage, dtoPage, "records"); + dtoPage.setRecords(dtoList); + return dtoPage; + } + + +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealDishServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealDishServiceImpl.java new file mode 100644 index 0000000..f486fb1 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealDishServiceImpl.java @@ -0,0 +1,17 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.SetmealDish; +import io.renren.modules.front.dao.SetmealDishMapper; +import io.renren.modules.front.service.SetmealDishService; +import org.springframework.stereotype.Service; + +/** + * 套餐菜品关系(SetmealDish)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Service(value = "setmealDishServiceImplFront") +public class SetmealDishServiceImpl extends ServiceImpl implements SetmealDishService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealServiceImpl.java new file mode 100644 index 0000000..46ea014 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/SetmealServiceImpl.java @@ -0,0 +1,55 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.Setmeal; +import io.renren.modules.front.bean.SetmealDish; +import io.renren.modules.front.dao.SetmealMapper; +import io.renren.modules.front.service.SetmealDishService; +import io.renren.modules.front.service.SetmealService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 套餐(Setmeal)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Service(value = "setmealServiceImplFront") +public class SetmealServiceImpl extends ServiceImpl implements SetmealService { + +// @Autowired +// private SetmealDishService setmealDishService; +// +// @Override +// public void saveSetmealDish(SetmealDTO setmealDTO) { +// //保存套餐信息 +// this.save(setmealDTO); +// //保存套餐菜品信息 +// List list = setmealDTO.getSetmealDishes().stream().map(setmealDish -> { +// setmealDish.setSetmealId(String.valueOf(setmealDTO.getId())); +// return setmealDish; +// }).collect(Collectors.toList()); +// setmealDishService.saveBatch(list); +// } +// +// @Override +// public void updateSetmealDish(SetmealDTO setmealDTO) { +// //保存套餐信息 +// this.updateById(setmealDTO); +// //清空原有菜品信息 +// LambdaUpdateWrapper luw = new LambdaUpdateWrapper<>(); +// luw.eq(SetmealDish::getSetmealId, setmealDTO.getId()); +// setmealDishService.remove(luw); +// //保存套餐新菜品信息 +// List list = setmealDTO.getSetmealDishes().stream().map(setmealDish -> { +// setmealDish.setSetmealId(String.valueOf(setmealDTO.getId())); +// return setmealDish; +// }).collect(Collectors.toList()); +// setmealDishService.saveBatch(list); +// } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/ShoppingCartServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/ShoppingCartServiceImpl.java new file mode 100644 index 0000000..39ca960 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/ShoppingCartServiceImpl.java @@ -0,0 +1,71 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.ShoppingCart; +import io.renren.modules.front.dao.ShoppingCartMapper; +import io.renren.modules.front.service.ShoppingCartService; +import io.renren.modules.front.utils.BaseContext; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +/** + * 购物车(ShoppingCart)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:45 + */ +@Service(value = "shoppingCartServiceImplFront") +public class ShoppingCartServiceImpl extends ServiceImpl implements ShoppingCartService { + @Override + public ShoppingCart add(ShoppingCart shoppingCart) { + //查询当前购物车的菜品/套餐是否在数据库存在 + //若存在则number+1,否则添加到购物车表中 + //1.1.查询当前用户的购物车信息 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(ShoppingCart::getUserId, BaseContext.getCurrentId()); + //1.2.判断查询的是菜品还是套餐 + Long dishId = shoppingCart.getDishId(); + if(dishId != null){ + lqw.eq(ShoppingCart::getDishId, dishId); + } else { + lqw.eq(ShoppingCart::getSetmealId, shoppingCart.getSetmealId()); + } + //1.3.执行查询 + ShoppingCart cart = this.getOne(lqw); + //2 如果存在,数量+1 + if(cart != null){ + cart.setNumber(cart.getNumber()+1); + this.updateById(cart); + } else { + //3 不存在,添加到购物车表中 + shoppingCart.setCreateDate(LocalDateTime.now()); + shoppingCart.setUserId(BaseContext.getCurrentId()); + shoppingCart.setNumber(1); + this.save(shoppingCart); + cart = shoppingCart; + } + return cart; + } + + @Override + public ShoppingCart sub(ShoppingCart cart) { + //查询菜品/套餐的购物车数据 + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(ShoppingCart::getUserId, BaseContext.getCurrentId()); + if(cart.getDishId() != null){ + lqw.eq(ShoppingCart::getDishId, cart.getDishId()); + } else { + lqw.eq(ShoppingCart::getSetmealId, cart.getSetmealId()); + } + ShoppingCart shoppingCart = this.getOne(lqw); + //修改数量 + if(shoppingCart.getNumber() == 1){ + this.removeById(shoppingCart); + } + shoppingCart.setNumber(shoppingCart.getNumber()-1); + this.updateById(shoppingCart); + return shoppingCart; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/service/impl/UserServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/front/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..3d5197c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/service/impl/UserServiceImpl.java @@ -0,0 +1,17 @@ +package io.renren.modules.front.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.modules.front.bean.User; +import io.renren.modules.front.dao.UserMapper; +import io.renren.modules.front.service.UserService; +import org.springframework.stereotype.Service; + +/** + * 用户信息(User)表服务实现类 + * + * @author 张宇轩 + * @since 2023-05-29 11:08:46 + */ +@Service(value = "userServiceImplFront") +public class UserServiceImpl extends ServiceImpl implements UserService { +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/utils/BaseContext.java b/renren-admin/src/main/java/io/renren/modules/front/utils/BaseContext.java new file mode 100644 index 0000000..31e789e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/utils/BaseContext.java @@ -0,0 +1,24 @@ +package io.renren.modules.front.utils; + +/** + * @author : 张宇轩 + * @createTime : 2023/5/30 - 15:51 + * 基于ThreadLocal封装工具类,用户保存和获取当前登录用户id + */ +public class BaseContext { + private static ThreadLocal threadLocal = new ThreadLocal<>(); + /** + * 设置值 + * @param id + */ + public static void setCurrentId(Long id){ + threadLocal.set(id); + } + /** + * 获取值 + * @return + */ + public static Long getCurrentId(){ + return threadLocal.get(); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/utils/R.java b/renren-admin/src/main/java/io/renren/modules/front/utils/R.java new file mode 100644 index 0000000..57b388a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/utils/R.java @@ -0,0 +1,35 @@ +package io.renren.modules.front.utils; + +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; + +/** + * 通用返回结果,服务端响应的数据最终都会封装成此对象 + * @param + */ +@Data +public class R { + private Integer code; //编码:1成功,0和其它数字为失败 + private String msg; //错误信息 + private T data; //数据 + private Map map = new HashMap(); //动态数据 + + public static R success(T object) { + R r = new R(); + r.data = object; + r.code = 1; + return r; + } + public static R error(String msg) { + R r = new R(); + r.msg = msg; + r.code = 0; + return r; + } + public R add(String key, Object value) { + this.map.put(key, value); + return this; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/front/utils/SendEmailUtils.java b/renren-admin/src/main/java/io/renren/modules/front/utils/SendEmailUtils.java new file mode 100644 index 0000000..8b74cbd --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/utils/SendEmailUtils.java @@ -0,0 +1,53 @@ +package io.renren.modules.front.utils; + +import org.apache.commons.mail.EmailException; +import org.apache.commons.mail.HtmlEmail; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @author : 张宇轩 + * @createTime : 2023/1/19 - 15:43 + */ +@Component +public class SendEmailUtils { + private static String userName; + private static String password; + + @Value("${email.userName}") + public void setUserName(String userName) { + SendEmailUtils.userName = userName; + } + + @Value("${email.password}") + public void setPassword(String password) { + SendEmailUtils.password = password; + } + + + /** + * 发送验证码 + * @param email 接收邮箱 + * @param code 验证码 + */ + public static void sendAuthCodeEmail(String email,String code) throws EmailException { + HtmlEmail mail = new HtmlEmail(); + /*发送邮件的服务器 126邮箱为smtp.126.com,163邮箱为163.smtp.com,QQ为smtp.qq.com*/ + mail.setHostName("smtp.qq.com"); + /*不设置发送的消息有可能是乱码*/ + mail.setCharset("UTF-8"); + /*IMAP/SMTP服务的密码 username为你开启发送验证码功能的邮箱号 password为你在qq邮箱获取到的一串字符串*/ + mail.setAuthentication(userName, password); + /*发送邮件的邮箱和发件人*/ + mail.setFrom(userName, "美食元素"); + /*使用安全链接*/ + mail.setSSLOnConnect(true); + /*接收的邮箱*/ + mail.addTo(email); + /*设置邮件的主题*/ + mail.setSubject("登录验证码"); + /*设置邮件的内容*/ + mail.setMsg("尊敬的用户:你好! 登录验证码为:" + code + "(有效期为一分钟)"); + mail.send();//发送 + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/front/utils/ValidateCodeUtils.java b/renren-admin/src/main/java/io/renren/modules/front/utils/ValidateCodeUtils.java new file mode 100644 index 0000000..645e3d2 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/front/utils/ValidateCodeUtils.java @@ -0,0 +1,43 @@ +package io.renren.modules.front.utils; + +import java.util.Random; + +/** + * 随机生成验证码工具类 + */ +public class ValidateCodeUtils { + /** + * 随机生成验证码 + * @param length 长度为4位或者6位 + * @return + */ + public static Integer generateValidateCode(int length){ + Integer code =null; + if(length == 4){ + code = new Random().nextInt(9999);//生成随机数,最大为9999 + if(code < 1000){ + code = code + 1000;//保证随机数为4位数字 + } + }else if(length == 6){ + code = new Random().nextInt(999999);//生成随机数,最大为999999 + if(code < 100000){ + code = code + 100000;//保证随机数为6位数字 + } + }else{ + throw new RuntimeException("只能生成4位或6位数字验证码"); + } + return code; + } + + /** + * 随机生成指定长度字符串验证码 + * @param length 长度 + * @return + */ + public static String generateValidateCode4String(int length){ + Random rdm = new Random(); + String hash1 = Integer.toHexString(rdm.nextInt()); + String capstr = hash1.substring(0, length); + return capstr; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/config/ScheduleConfig.java b/renren-admin/src/main/java/io/renren/modules/job/config/ScheduleConfig.java new file mode 100644 index 0000000..284d180 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/config/ScheduleConfig.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; + +import javax.sql.DataSource; +import java.util.Properties; + +/** + * 定时任务配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class ScheduleConfig { + + @Bean + public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) { + SchedulerFactoryBean factory = new SchedulerFactoryBean(); + factory.setDataSource(dataSource); + + //quartz参数 + Properties prop = new Properties(); + prop.put("org.quartz.scheduler.instanceName", "RenrenScheduler"); + prop.put("org.quartz.scheduler.instanceId", "AUTO"); + //线程池配置 + prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); + prop.put("org.quartz.threadPool.threadCount", "20"); + prop.put("org.quartz.threadPool.threadPriority", "5"); + //JobStore配置 + prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); + //集群配置 + prop.put("org.quartz.jobStore.isClustered", "true"); + prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); + prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); + + prop.put("org.quartz.jobStore.misfireThreshold", "12000"); + prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); + prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); + + //PostgreSQL数据库,需要打开此注释 + //prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"); + + factory.setQuartzProperties(prop); + + factory.setSchedulerName("RenrenScheduler"); + //延时启动 + factory.setStartupDelay(30); + factory.setApplicationContextSchedulerContextKey("applicationContextKey"); + //可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 + factory.setOverwriteExistingJobs(true); + //设置自动启动,默认为true + factory.setAutoStartup(true); + + return factory; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java b/renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java new file mode 100644 index 0000000..fcb1566 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.Result; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.job.dto.ScheduleJobDTO; +import io.renren.modules.job.service.ScheduleJobService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.Map; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/schedule") +@Api(tags="定时任务") +public class ScheduleJobController { + @Autowired + private ScheduleJobService scheduleJobService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "beanName", value = "beanName", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:schedule:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = scheduleJobService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:schedule:info") + public Result info(@PathVariable("id") Long id){ + ScheduleJobDTO schedule = scheduleJobService.get(id); + + return new Result().ok(schedule); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:schedule:save") + public Result save(@RequestBody ScheduleJobDTO dto){ + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + scheduleJobService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:schedule:update") + public Result update(@RequestBody ScheduleJobDTO dto){ + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + scheduleJobService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:schedule:delete") + public Result delete(@RequestBody Long[] ids){ + scheduleJobService.deleteBatch(ids); + + return new Result(); + } + + @PutMapping("/run") + @ApiOperation("立即执行") + @LogOperation("立即执行") + @RequiresPermissions("sys:schedule:run") + public Result run(@RequestBody Long[] ids){ + scheduleJobService.run(ids); + + return new Result(); + } + + @PutMapping("/pause") + @ApiOperation("暂停") + @LogOperation("暂停") + @RequiresPermissions("sys:schedule:pause") + public Result pause(@RequestBody Long[] ids){ + scheduleJobService.pause(ids); + + return new Result(); + } + + @PutMapping("/resume") + @ApiOperation("恢复") + @LogOperation("恢复") + @RequiresPermissions("sys:schedule:resume") + public Result resume(@RequestBody Long[] ids){ + scheduleJobService.resume(ids); + + return new Result(); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java b/renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java new file mode 100644 index 0000000..6d3c8da --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.controller; + +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.Result; +import io.renren.modules.job.dto.ScheduleJobLogDTO; +import io.renren.modules.job.service.ScheduleJobLogService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.Map; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/scheduleLog") +@Api(tags="定时任务日志") +public class ScheduleJobLogController { + @Autowired + private ScheduleJobLogService scheduleJobLogService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "jobId", value = "jobId", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:schedule:log") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = scheduleJobLogService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:schedule:log") + public Result info(@PathVariable("id") Long id){ + ScheduleJobLogDTO log = scheduleJobLogService.get(id); + + return new Result().ok(log); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java b/renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java new file mode 100644 index 0000000..c5e6f91 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.job.entity.ScheduleJobEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Map; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface ScheduleJobDao extends BaseDao { + + /** + * 批量更新状态 + */ + int updateBatch(Map map); +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java b/renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java new file mode 100644 index 0000000..9c46eb3 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.job.entity.ScheduleJobLogEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface ScheduleJobLogDao extends BaseDao { + +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobDTO.java b/renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobDTO.java new file mode 100644 index 0000000..7ca4a22 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobDTO.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "定时任务") +public class ScheduleJobDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "spring bean名称") + @NotBlank(message = "{schedule.bean.require}", groups = DefaultGroup.class) + private String beanName; + + @ApiModelProperty(value = "参数") + private String params; + + @ApiModelProperty(value = "cron表达式") + @NotBlank(message = "{schedule.cron.require}", groups = DefaultGroup.class) + private String cronExpression; + + @ApiModelProperty(value = "任务状态 0:暂停 1:正常") + @Range(min=0, max=1, message = "{schedule.status.range}", groups = DefaultGroup.class) + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobLogDTO.java b/renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobLogDTO.java new file mode 100644 index 0000000..0a2459a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/dto/ScheduleJobLogDTO.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "定时任务日志") +public class ScheduleJobLogDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "任务id") + private Long jobId; + + @ApiModelProperty(value = "spring bean名称") + private String beanName; + + @ApiModelProperty(value = "参数") + private String params; + + @ApiModelProperty(value = "任务状态 0:失败 1:成功") + private Integer status; + + @ApiModelProperty(value = "失败信息") + private String error; + + @ApiModelProperty(value = "耗时(单位:毫秒)") + private Integer times; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java b/renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java new file mode 100644 index 0000000..7c584bd --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("schedule_job") +public class ScheduleJobEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * spring bean名称 + */ + private String beanName; + /** + * 参数 + */ + private String params; + /** + * cron表达式 + */ + private String cronExpression; + /** + * 任务状态 0:暂停 1:正常 + */ + private Integer status; + /** + * 备注 + */ + private String remark; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java b/renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java new file mode 100644 index 0000000..0d4c9eb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("schedule_job_log") +public class ScheduleJobLogEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * 任务id + */ + private Long jobId; + /** + * spring bean名称 + */ + private String beanName; + /** + * 参数 + */ + private String params; + /** + * 任务状态 0:失败 1:成功 + */ + private Integer status; + /** + * 失败信息 + */ + private String error; + /** + * 耗时(单位:毫秒) + */ + private Integer times; + /** + * 创建时间 + */ + private Date createDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/init/JobCommandLineRunner.java b/renren-admin/src/main/java/io/renren/modules/job/init/JobCommandLineRunner.java new file mode 100644 index 0000000..eb79ee8 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/init/JobCommandLineRunner.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.init; + +import io.renren.modules.job.dao.ScheduleJobDao; +import io.renren.modules.job.entity.ScheduleJobEntity; +import io.renren.modules.job.utils.ScheduleUtils; +import org.quartz.CronTrigger; +import org.quartz.Scheduler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 初始化定时任务数据 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class JobCommandLineRunner implements CommandLineRunner { + @Autowired + private Scheduler scheduler; + @Autowired + private ScheduleJobDao scheduleJobDao; + + @Override + public void run(String... args) { + List scheduleJobList = scheduleJobDao.selectList(null); + for(ScheduleJobEntity scheduleJob : scheduleJobList){ + CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getId()); + //如果不存在,则创建 + if(cronTrigger == null) { + ScheduleUtils.createScheduleJob(scheduler, scheduleJob); + }else { + ScheduleUtils.updateScheduleJob(scheduler, scheduleJob); + } + } + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java b/renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java new file mode 100644 index 0000000..8c4e5bb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.job.dto.ScheduleJobLogDTO; +import io.renren.modules.job.entity.ScheduleJobLogEntity; + +import java.util.Map; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ScheduleJobLogService extends BaseService { + + PageData page(Map params); + + ScheduleJobLogDTO get(Long id); +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobService.java b/renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobService.java new file mode 100644 index 0000000..970f8c8 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/service/ScheduleJobService.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.job.dto.ScheduleJobDTO; +import io.renren.modules.job.entity.ScheduleJobEntity; + +import java.util.Map; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ScheduleJobService extends BaseService { + + PageData page(Map params); + + ScheduleJobDTO get(Long id); + + /** + * 保存定时任务 + */ + void save(ScheduleJobDTO dto); + + /** + * 更新定时任务 + */ + void update(ScheduleJobDTO dto); + + /** + * 批量删除定时任务 + */ + void deleteBatch(Long[] ids); + + /** + * 批量更新定时任务状态 + */ + int updateBatch(Long[] ids, int status); + + /** + * 立即执行 + */ + void run(Long[] ids); + + /** + * 暂停运行 + */ + void pause(Long[] ids); + + /** + * 恢复运行 + */ + void resume(Long[] ids); +} diff --git a/renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java new file mode 100644 index 0000000..9a2cc08 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.job.dao.ScheduleJobLogDao; +import io.renren.modules.job.dto.ScheduleJobLogDTO; +import io.renren.modules.job.entity.ScheduleJobLogEntity; +import io.renren.modules.job.service.ScheduleJobLogService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +public class ScheduleJobLogServiceImpl extends BaseServiceImpl implements ScheduleJobLogService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + return getPageData(page, ScheduleJobLogDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String jobId = (String)params.get("jobId"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(jobId), "job_id", jobId); + + return wrapper; + } + + @Override + public ScheduleJobLogDTO get(Long id) { + ScheduleJobLogEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, ScheduleJobLogDTO.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java new file mode 100644 index 0000000..c8dcb79 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.job.dao.ScheduleJobDao; +import io.renren.modules.job.dto.ScheduleJobDTO; +import io.renren.modules.job.entity.ScheduleJobEntity; +import io.renren.modules.job.service.ScheduleJobService; +import io.renren.modules.job.utils.ScheduleUtils; +import org.apache.commons.lang3.StringUtils; +import org.quartz.Scheduler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +@Service +public class ScheduleJobServiceImpl extends BaseServiceImpl implements ScheduleJobService { + @Autowired + private Scheduler scheduler; + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + return getPageData(page, ScheduleJobDTO.class); + } + + @Override + public ScheduleJobDTO get(Long id) { + ScheduleJobEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, ScheduleJobDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String beanName = (String)params.get("beanName"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.like(StringUtils.isNotBlank(beanName), "bean_name", beanName); + + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(ScheduleJobDTO dto) { + ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class); + + entity.setStatus(Constant.ScheduleStatus.NORMAL.getValue()); + this.insert(entity); + + ScheduleUtils.createScheduleJob(scheduler, entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ScheduleJobDTO dto) { + ScheduleJobEntity entity = ConvertUtils.sourceToTarget(dto, ScheduleJobEntity.class); + + ScheduleUtils.updateScheduleJob(scheduler, entity); + + this.updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteBatch(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.deleteScheduleJob(scheduler, id); + } + + //删除数据 + this.deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public int updateBatch(Long[] ids, int status){ + Map map = new HashMap<>(2); + map.put("ids", ids); + map.put("status", status); + return baseDao.updateBatch(map); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void run(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.run(scheduler, this.selectById(id)); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void pause(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.pauseJob(scheduler, id); + } + + updateBatch(ids, Constant.ScheduleStatus.PAUSE.getValue()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void resume(Long[] ids) { + for(Long id : ids){ + ScheduleUtils.resumeJob(scheduler, id); + } + + updateBatch(ids, Constant.ScheduleStatus.NORMAL.getValue()); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/task/ITask.java b/renren-admin/src/main/java/io/renren/modules/job/task/ITask.java new file mode 100644 index 0000000..c6e09b9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/task/ITask.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.task; + +/** + * 定时任务接口,所有定时任务都要实现该接口 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface ITask { + + /** + * 执行定时任务接口 + * + * @param params 参数,多参数使用JSON数据 + */ + void run(String params); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/task/TestTask.java b/renren-admin/src/main/java/io/renren/modules/job/task/TestTask.java new file mode 100644 index 0000000..7dc12ea --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/task/TestTask.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.task; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * 测试定时任务(演示Demo,可删除) + * + * testTask为spring bean的名称 + * + * @author Mark sunlightcs@gmail.com + */ +@Component("testTask") +public class TestTask implements ITask{ + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void run(String params){ + logger.debug("TestTask定时任务正在执行,参数为:{}", params); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleJob.java b/renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleJob.java new file mode 100644 index 0000000..257ba18 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleJob.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.utils; + +import io.renren.common.constant.Constant; +import io.renren.common.exception.ExceptionUtils; +import io.renren.common.utils.SpringContextUtils; +import io.renren.modules.job.entity.ScheduleJobEntity; +import io.renren.modules.job.entity.ScheduleJobLogEntity; +import io.renren.modules.job.service.ScheduleJobLogService; +import org.quartz.JobExecutionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import java.lang.reflect.Method; +import java.util.Date; + + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +public class ScheduleJob extends QuartzJobBean { + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + protected void executeInternal(JobExecutionContext context) { + ScheduleJobEntity scheduleJob = (ScheduleJobEntity) context.getMergedJobDataMap(). + get(ScheduleUtils.JOB_PARAM_KEY); + + //数据库保存执行记录 + ScheduleJobLogEntity log = new ScheduleJobLogEntity(); + log.setJobId(scheduleJob.getId()); + log.setBeanName(scheduleJob.getBeanName()); + log.setParams(scheduleJob.getParams()); + log.setCreateDate(new Date()); + + //任务开始时间 + long startTime = System.currentTimeMillis(); + + try { + //执行任务 + logger.info("任务准备执行,任务ID:{}", scheduleJob.getId()); + Object target = SpringContextUtils.getBean(scheduleJob.getBeanName()); + Method method = target.getClass().getDeclaredMethod("run", String.class); + method.invoke(target, scheduleJob.getParams()); + + //任务执行总时长 + long times = System.currentTimeMillis() - startTime; + log.setTimes((int)times); + //任务状态 + log.setStatus(Constant.SUCCESS); + + logger.info("任务执行完毕,任务ID:{} 总共耗时:{} 毫秒", scheduleJob.getId(), times); + } catch (Exception e) { + logger.error("任务执行失败,任务ID:{}", scheduleJob.getId(), e); + + //任务执行总时长 + long times = System.currentTimeMillis() - startTime; + log.setTimes((int)times); + + //任务状态 + log.setStatus(Constant.FAIL); + log.setError(ExceptionUtils.getErrorStackTrace(e)); + }finally { + //获取spring bean + ScheduleJobLogService scheduleJobLogService = SpringContextUtils.getBean(ScheduleJobLogService.class); + scheduleJobLogService.insert(log); + } + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java b/renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java new file mode 100644 index 0000000..7e141b9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.utils; + +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.modules.job.entity.ScheduleJobEntity; +import org.quartz.*; + +/** + * 定时任务工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ScheduleUtils { + private final static String JOB_NAME = "TASK_"; + /** + * 任务调度参数key + */ + public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY"; + + /** + * 获取触发器key + */ + public static TriggerKey getTriggerKey(Long jobId) { + return TriggerKey.triggerKey(JOB_NAME + jobId); + } + + /** + * 获取jobKey + */ + public static JobKey getJobKey(Long jobId) { + return JobKey.jobKey(JOB_NAME + jobId); + } + + /** + * 获取表达式触发器 + */ + public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) { + try { + return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + //构建job信息 + JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getId())).build(); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + //按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getId())).withSchedule(scheduleBuilder).build(); + + //放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(JOB_PARAM_KEY, scheduleJob); + + scheduler.scheduleJob(jobDetail, trigger); + + //暂停任务 + if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ + pauseJob(scheduler, scheduleJob.getId()); + } + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 更新定时任务 + */ + public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + TriggerKey triggerKey = getTriggerKey(scheduleJob.getId()); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getId()); + + //按新的cronExpression表达式重新构建trigger + trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); + + //参数 + trigger.getJobDataMap().put(JOB_PARAM_KEY, scheduleJob); + + scheduler.rescheduleJob(triggerKey, trigger); + + //暂停任务 + if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ + pauseJob(scheduler, scheduleJob.getId()); + } + + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 立即执行任务 + */ + public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + //参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(JOB_PARAM_KEY, scheduleJob); + + scheduler.triggerJob(getJobKey(scheduleJob.getId()), dataMap); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 暂停任务 + */ + public static void pauseJob(Scheduler scheduler, Long jobId) { + try { + scheduler.pauseJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 恢复任务 + */ + public static void resumeJob(Scheduler scheduler, Long jobId) { + try { + scheduler.resumeJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } + + /** + * 删除定时任务 + */ + public static void deleteScheduleJob(Scheduler scheduler, Long jobId) { + try { + scheduler.deleteJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RenException(ErrorCode.JOB_ERROR, e); + } + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogErrorController.java b/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogErrorController.java new file mode 100644 index 0000000..c62a07d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogErrorController.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.modules.log.dto.SysLogErrorDTO; +import io.renren.modules.log.excel.SysLogErrorExcel; +import io.renren.modules.log.service.SysLogErrorService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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 springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/log/error") +@Api(tags="异常日志") +public class SysLogErrorController { + @Autowired + private SysLogErrorService sysLogErrorService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:log:error") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysLogErrorService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:log:error") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysLogErrorService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysLogErrorExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogLoginController.java b/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogLoginController.java new file mode 100644 index 0000000..e95352d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogLoginController.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.modules.log.dto.SysLogLoginDTO; +import io.renren.modules.log.excel.SysLogLoginExcel; +import io.renren.modules.log.service.SysLogLoginService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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 springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/log/login") +@Api(tags="登录日志") +public class SysLogLoginController { + @Autowired + private SysLogLoginService sysLogLoginService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "status", value = "状态 0:失败 1:成功 2:账号已锁定", paramType = "query", dataType="int"), + @ApiImplicitParam(name = "creatorName", value = "用户名", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:log:login") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysLogLoginService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @ApiImplicitParams({ + @ApiImplicitParam(name = "status", value = "状态 0:失败 1:成功 2:账号已锁定", paramType = "query", dataType="int"), + @ApiImplicitParam(name = "creatorName", value = "用户名", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:log:login") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysLogLoginService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysLogLoginExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogOperationController.java b/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogOperationController.java new file mode 100644 index 0000000..a93eb15 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/controller/SysLogOperationController.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.modules.log.dto.SysLogOperationDTO; +import io.renren.modules.log.excel.SysLogOperationExcel; +import io.renren.modules.log.service.SysLogOperationService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +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 springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/log/operation") +@Api(tags="操作日志") +public class SysLogOperationController { + @Autowired + private SysLogOperationService sysLogOperationService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "status", value = "状态 0:失败 1:成功", paramType = "query", dataType="int") + }) + @RequiresPermissions("sys:log:operation") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysLogOperationService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:log:operation") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysLogOperationService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysLogOperationExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogErrorDao.java b/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogErrorDao.java new file mode 100644 index 0000000..cf7e397 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogErrorDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.log.entity.SysLogErrorEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysLogErrorDao extends BaseDao { + +} diff --git a/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogLoginDao.java b/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogLoginDao.java new file mode 100644 index 0000000..3ed5087 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogLoginDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.log.entity.SysLogLoginEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysLogLoginDao extends BaseDao { + +} diff --git a/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogOperationDao.java b/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogOperationDao.java new file mode 100644 index 0000000..5be96ca --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/dao/SysLogOperationDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.log.entity.SysLogOperationEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysLogOperationDao extends BaseDao { + +} diff --git a/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogErrorDTO.java b/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogErrorDTO.java new file mode 100644 index 0000000..7df2a4c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogErrorDTO.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "异常日志") +public class SysLogErrorDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + @ApiModelProperty(value = "请求URI") + private String requestUri; + @ApiModelProperty(value = "请求方式") + private String requestMethod; + @ApiModelProperty(value = "请求参数") + private String requestParams; + @ApiModelProperty(value = "用户代理") + private String userAgent; + @ApiModelProperty(value = "操作IP") + private String ip; + @ApiModelProperty(value = "异常信息") + private String errorInfo; + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogLoginDTO.java b/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogLoginDTO.java new file mode 100644 index 0000000..c638d60 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogLoginDTO.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "登录日志") +public class SysLogLoginDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "用户操作 0:用户登录 1:用户退出") + private Integer operation; + + @ApiModelProperty(value = "状态 0:失败 1:成功 2:账号已锁定") + private Integer status; + + @ApiModelProperty(value = "用户代理") + private String userAgent; + + @ApiModelProperty(value = "操作IP") + private String ip; + + @ApiModelProperty(value = "用户名") + private String creatorName; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogOperationDTO.java b/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogOperationDTO.java new file mode 100644 index 0000000..133b3c4 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/dto/SysLogOperationDTO.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "操作日志") +public class SysLogOperationDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "用户操作") + private String operation; + + @ApiModelProperty(value = "请求URI") + private String requestUri; + + @ApiModelProperty(value = "请求方式") + private String requestMethod; + + @ApiModelProperty(value = "请求参数") + private String requestParams; + + @ApiModelProperty(value = "请求时长(毫秒)") + private Integer requestTime; + + @ApiModelProperty(value = "用户代理") + private String userAgent; + + @ApiModelProperty(value = "操作IP") + private String ip; + + @ApiModelProperty(value = "状态 0:失败 1:成功") + private Integer status; + + @ApiModelProperty(value = "用户名") + private String creatorName; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogErrorEntity.java b/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogErrorEntity.java new file mode 100644 index 0000000..b14a970 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogErrorEntity.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_log_error") +public class SysLogErrorEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 请求URI + */ + private String requestUri; + /** + * 请求方式 + */ + private String requestMethod; + /** + * 请求参数 + */ + private String requestParams; + /** + * 用户代理 + */ + private String userAgent; + /** + * 操作IP + */ + private String ip; + /** + * 异常信息 + */ + private String errorInfo; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogLoginEntity.java b/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogLoginEntity.java new file mode 100644 index 0000000..2be0651 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogLoginEntity.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_log_login") +public class SysLogLoginEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 用户操作 0:用户登录 1:用户退出 + */ + private Integer operation; + /** + * 状态 0:失败 1:成功 2:账号已锁定 + */ + private Integer status; + /** + * 用户代理 + */ + private String userAgent; + /** + * 操作IP + */ + private String ip; + /** + * 用户名 + */ + private String creatorName; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogOperationEntity.java b/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogOperationEntity.java new file mode 100644 index 0000000..ac1ce1e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/entity/SysLogOperationEntity.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_log_operation") +public class SysLogOperationEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 用户操作 + */ + private String operation; + /** + * 请求URI + */ + private String requestUri; + /** + * 请求方式 + */ + private String requestMethod; + /** + * 请求参数 + */ + private String requestParams; + /** + * 请求时长(毫秒) + */ + private Integer requestTime; + /** + * 用户代理 + */ + private String userAgent; + /** + * 操作IP + */ + private String ip; + /** + * 状态 0:失败 1:成功 + */ + private Integer status; + /** + * 用户名 + */ + private String creatorName; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/enums/LoginOperationEnum.java b/renren-admin/src/main/java/io/renren/modules/log/enums/LoginOperationEnum.java new file mode 100644 index 0000000..a130c96 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/enums/LoginOperationEnum.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.enums; + +/** + * 登录操作枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum LoginOperationEnum { + /** + * 用户登录 + */ + LOGIN(0), + /** + * 用户退出 + */ + LOGOUT(1); + + private int value; + + LoginOperationEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/enums/LoginStatusEnum.java b/renren-admin/src/main/java/io/renren/modules/log/enums/LoginStatusEnum.java new file mode 100644 index 0000000..0292db3 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/enums/LoginStatusEnum.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.enums; + +/** + * 登录状态枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum LoginStatusEnum { + /** + * 失败 + */ + FAIL(0), + /** + * 成功 + */ + SUCCESS(1), + /** + * 账号已锁定 + */ + LOCK(2); + + private int value; + + LoginStatusEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/log/enums/OperationStatusEnum.java b/renren-admin/src/main/java/io/renren/modules/log/enums/OperationStatusEnum.java new file mode 100644 index 0000000..366e5fa --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/enums/OperationStatusEnum.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.enums; + +/** + * 操作状态枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum OperationStatusEnum { + /** + * 失败 + */ + FAIL(0), + /** + * 成功 + */ + SUCCESS(1); + + private int value; + + OperationStatusEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogErrorExcel.java b/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogErrorExcel.java new file mode 100644 index 0000000..16d73dc --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogErrorExcel.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysLogErrorExcel { + @Excel(name = "请求URI") + private String requestUri; + @Excel(name = "请求方式") + private String requestMethod; + @Excel(name = "请求参数") + private String requestParams; + @Excel(name = "User-Agent") + private String userAgent; + @Excel(name = "操作IP") + private String ip; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogLoginExcel.java b/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogLoginExcel.java new file mode 100644 index 0000000..12c736d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogLoginExcel.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysLogLoginExcel { + @Excel(name = "用户操作") + private String operation; + @Excel(name = "状态", replace = {"失败_0", "成功_1", "账号已锁定_1"}) + private Integer status; + @Excel(name = "User-Agent") + private String userAgent; + @Excel(name = "操作IP") + private String ip; + @Excel(name = "用户名") + private String creatorName; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogOperationExcel.java b/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogOperationExcel.java new file mode 100644 index 0000000..84fbcd0 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/excel/SysLogOperationExcel.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysLogOperationExcel { + @Excel(name = "用户操作") + private String operation; + @Excel(name = "请求URI") + private String requestUri; + @Excel(name = "请求方式") + private String requestMethod; + @Excel(name = "请求参数") + private String requestParams; + @Excel(name = "请求时长(毫秒)") + private Integer requestTime; + @Excel(name = "User-Agent") + private String userAgent; + @Excel(name = "操作IP") + private String ip; + @Excel(name = "状态", replace = {"失败_0", "成功_1"}) + private Integer status; + @Excel(name = "用户名") + private String creatorName; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/log/service/SysLogErrorService.java b/renren-admin/src/main/java/io/renren/modules/log/service/SysLogErrorService.java new file mode 100644 index 0000000..7ac9f66 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/service/SysLogErrorService.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.service; + + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.log.dto.SysLogErrorDTO; +import io.renren.modules.log.entity.SysLogErrorEntity; + +import java.util.List; +import java.util.Map; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysLogErrorService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + void save(SysLogErrorEntity entity); + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/service/SysLogLoginService.java b/renren-admin/src/main/java/io/renren/modules/log/service/SysLogLoginService.java new file mode 100644 index 0000000..39ed28d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/service/SysLogLoginService.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.log.dto.SysLogLoginDTO; +import io.renren.modules.log.entity.SysLogLoginEntity; + +import java.util.List; +import java.util.Map; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysLogLoginService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + void save(SysLogLoginEntity entity); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/service/SysLogOperationService.java b/renren-admin/src/main/java/io/renren/modules/log/service/SysLogOperationService.java new file mode 100644 index 0000000..5c7983e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/service/SysLogOperationService.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.log.dto.SysLogOperationDTO; +import io.renren.modules.log.entity.SysLogOperationEntity; + +import java.util.List; +import java.util.Map; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysLogOperationService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + void save(SysLogOperationEntity entity); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogErrorServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogErrorServiceImpl.java new file mode 100644 index 0000000..b249ae7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogErrorServiceImpl.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.log.dao.SysLogErrorDao; +import io.renren.modules.log.dto.SysLogErrorDTO; +import io.renren.modules.log.entity.SysLogErrorEntity; +import io.renren.modules.log.service.SysLogErrorService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 异常日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysLogErrorServiceImpl extends BaseServiceImpl implements SysLogErrorService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysLogErrorDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysLogErrorDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + QueryWrapper wrapper = new QueryWrapper<>(); + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysLogErrorEntity entity) { + insert(entity); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogLoginServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogLoginServiceImpl.java new file mode 100644 index 0000000..e2d180b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogLoginServiceImpl.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.log.dao.SysLogLoginDao; +import io.renren.modules.log.dto.SysLogLoginDTO; +import io.renren.modules.log.entity.SysLogLoginEntity; +import io.renren.modules.log.service.SysLogLoginService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 登录日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysLogLoginServiceImpl extends BaseServiceImpl implements SysLogLoginService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysLogLoginDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysLogLoginDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String status = (String) params.get("status"); + String creatorName = (String) params.get("creatorName"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(status), "status", status); + wrapper.like(StringUtils.isNotBlank(creatorName), "creator_name", creatorName); + + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysLogLoginEntity entity) { + insert(entity); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogOperationServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogOperationServiceImpl.java new file mode 100644 index 0000000..10f37cf --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/log/service/impl/SysLogOperationServiceImpl.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.log.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.log.dao.SysLogOperationDao; +import io.renren.modules.log.dto.SysLogOperationDTO; +import io.renren.modules.log.entity.SysLogOperationEntity; +import io.renren.modules.log.service.SysLogOperationService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * 操作日志 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysLogOperationServiceImpl extends BaseServiceImpl implements SysLogOperationService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysLogOperationDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysLogOperationDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String status = (String) params.get("status"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(status), "status", status); + + return wrapper; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysLogOperationEntity entity) { + insert(entity); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/AbstractCloudStorageService.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/AbstractCloudStorageService.java new file mode 100644 index 0000000..0bb7b46 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/AbstractCloudStorageService.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import io.renren.common.utils.DateUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.InputStream; +import java.util.Date; +import java.util.UUID; + +/** + * 云存储(支持七牛、阿里云、腾讯云) + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class AbstractCloudStorageService { + /** 云存储配置信息 */ + CloudStorageConfig config; + + /** + * 文件路径 + * @param prefix 前缀 + * @param suffix 后缀 + * @return 返回上传路径 + */ + public String getPath(String prefix, String suffix) { + //生成uuid + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + //文件路径 + String path = DateUtils.format(new Date(), "yyyyMMdd") + "/" + uuid; + + if(StringUtils.isNotBlank(prefix)){ + path = prefix + "/" + path; + } + + return path + "." + suffix; + } + + /** + * 文件上传 + * @param data 文件字节数组 + * @param path 文件路径,包含文件名 + * @return 返回http地址 + */ + public abstract String upload(byte[] data, String path); + + /** + * 文件上传 + * @param data 文件字节数组 + * @param suffix 后缀 + * @return 返回http地址 + */ + public abstract String uploadSuffix(byte[] data, String suffix); + + /** + * 文件上传 + * @param inputStream 字节流 + * @param path 文件路径,包含文件名 + * @return 返回http地址 + */ + public abstract String upload(InputStream inputStream, String path); + + /** + * 文件上传 + * @param inputStream 字节流 + * @param suffix 后缀 + * @return 返回http地址 + */ + public abstract String uploadSuffix(InputStream inputStream, String suffix); + +} diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java new file mode 100644 index 0000000..9754dbb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import com.aliyun.oss.OSSClient; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/** + * 阿里云存储 + * + * @author Mark sunlightcs@gmail.com + */ +public class AliyunCloudStorageService extends AbstractCloudStorageService { + + public AliyunCloudStorageService(CloudStorageConfig config){ + this.config = config; + } + + @Override + public String upload(byte[] data, String path) { + return upload(new ByteArrayInputStream(data), path); + } + + @Override + public String upload(InputStream inputStream, String path) { + OSSClient client = new OSSClient(config.getAliyunEndPoint(), config.getAliyunAccessKeyId(), + config.getAliyunAccessKeySecret()); + try { + client.putObject(config.getAliyunBucketName(), path, inputStream); + client.shutdown(); + } catch (Exception e){ + throw new RenException(ErrorCode.OSS_UPLOAD_FILE_ERROR, e, ""); + } + + return config.getAliyunDomain() + "/" + path; + } + + @Override + public String uploadSuffix(byte[] data, String suffix) { + return upload(data, getPath(config.getAliyunPrefix(), suffix)); + } + + @Override + public String uploadSuffix(InputStream inputStream, String suffix) { + return upload(inputStream, getPath(config.getAliyunPrefix(), suffix)); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java new file mode 100644 index 0000000..4b8225f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import io.renren.common.validator.group.AliyunGroup; +import io.renren.common.validator.group.QcloudGroup; +import io.renren.common.validator.group.QiniuGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Range; +import org.hibernate.validator.constraints.URL; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 云存储配置信息 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "云存储配置信息") +public class CloudStorageConfig implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "类型 1:七牛 2:阿里云 3:腾讯云 4:FastDFS 5:本地上传 6:MinIO") + @Range(min=1, max=6, message = "{oss.type.range}") + private Integer type; + + @ApiModelProperty(value = "七牛绑定的域名") + @NotBlank(message="{qiniu.domain.require}", groups = QiniuGroup.class) + @URL(message = "{qiniu.domain.url}", groups = QiniuGroup.class) + private String qiniuDomain; + + @ApiModelProperty(value = "七牛路径前缀") + private String qiniuPrefix; + + @ApiModelProperty(value = "七牛ACCESS_KEY") + @NotBlank(message="{qiniu.accesskey.require}", groups = QiniuGroup.class) + private String qiniuAccessKey; + + @ApiModelProperty(value = "七牛SECRET_KEY") + @NotBlank(message="{qiniu.secretkey.require}", groups = QiniuGroup.class) + private String qiniuSecretKey; + + @ApiModelProperty(value = "七牛存储空间名") + @NotBlank(message="{qiniu.bucketname.require}", groups = QiniuGroup.class) + private String qiniuBucketName; + + @ApiModelProperty(value = "阿里云绑定的域名") + @NotBlank(message="{aliyun.domain.require}", groups = AliyunGroup.class) + @URL(message = "{aliyun.domain.url}", groups = AliyunGroup.class) + private String aliyunDomain; + + @ApiModelProperty(value = "阿里云路径前缀") + private String aliyunPrefix; + + @ApiModelProperty(value = "阿里云EndPoint") + @NotBlank(message="{aliyun.endPoint.require}", groups = AliyunGroup.class) + private String aliyunEndPoint; + + @ApiModelProperty(value = "阿里云AccessKeyId") + @NotBlank(message="{aliyun.accesskeyid.require}", groups = AliyunGroup.class) + private String aliyunAccessKeyId; + + @ApiModelProperty(value = "阿里云AccessKeySecret") + @NotBlank(message="{aliyun.accesskeysecret.require}", groups = AliyunGroup.class) + private String aliyunAccessKeySecret; + + @ApiModelProperty(value = "阿里云BucketName") + @NotBlank(message="{aliyun.bucketname.require}", groups = AliyunGroup.class) + private String aliyunBucketName; + + @ApiModelProperty(value = "腾讯云绑定的域名") + @NotBlank(message="{qcloud.domain.require}", groups = QcloudGroup.class) + @URL(message = "{qcloud.domain.url}", groups = QcloudGroup.class) + private String qcloudDomain; + + @ApiModelProperty(value = "腾讯云路径前缀") + private String qcloudPrefix; + + @ApiModelProperty(value = "腾讯云AppId") + @NotNull(message="{qcloud.appid.require}", groups = QcloudGroup.class) + private Integer qcloudAppId; + + @ApiModelProperty(value = "腾讯云SecretId") + @NotBlank(message="{qcloud.secretId.require}", groups = QcloudGroup.class) + private String qcloudSecretId; + + @ApiModelProperty(value = "腾讯云SecretKey") + @NotBlank(message="{qcloud.secretkey.require}", groups = QcloudGroup.class) + private String qcloudSecretKey; + + @ApiModelProperty(value = "腾讯云BucketName") + @NotBlank(message="{qcloud.bucketname.require}", groups = QcloudGroup.class) + private String qcloudBucketName; + + @ApiModelProperty(value = "腾讯云COS所属地区") + @NotBlank(message="{qcloud.region.require}", groups = QcloudGroup.class) + private String qcloudRegion; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java new file mode 100644 index 0000000..f7d5bd5 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import io.renren.common.constant.Constant; +import io.renren.common.utils.SpringContextUtils; +import io.renren.modules.sys.service.SysParamsService; + +/** + * 文件上传Factory + * @author Mark sunlightcs@gmail.com + */ +public final class OSSFactory { + private static SysParamsService sysParamsService; + + static { + OSSFactory.sysParamsService = SpringContextUtils.getBean(SysParamsService.class); + } + + public static AbstractCloudStorageService build(){ + //获取云存储配置信息 + CloudStorageConfig config = sysParamsService.getValueObject(Constant.CLOUD_STORAGE_CONFIG_KEY, CloudStorageConfig.class); + + if(config.getType() == Constant.CloudService.QINIU.getValue()){ + return new QiniuCloudStorageService(config); + }else if(config.getType() == Constant.CloudService.ALIYUN.getValue()){ + return new AliyunCloudStorageService(config); + }else if(config.getType() == Constant.CloudService.QCLOUD.getValue()){ + return new QcloudCloudStorageService(config); + } + + return null; + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java new file mode 100644 index 0000000..80d05d6 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import com.qcloud.cos.COSClient; +import com.qcloud.cos.ClientConfig; +import com.qcloud.cos.auth.BasicCOSCredentials; +import com.qcloud.cos.auth.COSCredentials; +import com.qcloud.cos.model.ObjectMetadata; +import com.qcloud.cos.model.PutObjectRequest; +import com.qcloud.cos.model.PutObjectResult; +import com.qcloud.cos.region.Region; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * 腾讯云存储 + * + * @author Mark sunlightcs@gmail.com + */ +public class QcloudCloudStorageService extends AbstractCloudStorageService { + private COSCredentials credentials; + private ClientConfig clientConfig; + + public QcloudCloudStorageService(CloudStorageConfig config){ + this.config = config; + + //初始化 + init(); + } + + private void init(){ + //1、初始化用户身份信息(secretId, secretKey) + credentials = new BasicCOSCredentials(config.getQcloudSecretId(), config.getQcloudSecretKey()); + + //2、设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224 + clientConfig = new ClientConfig(new Region(config.getQcloudRegion())); + } + + @Override + public String upload(byte[] data, String path) { + return upload(new ByteArrayInputStream(data), path); + } + + @Override + public String upload(InputStream inputStream, String path) { + try { + COSClient client = new COSClient(credentials, clientConfig); + + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(inputStream.available()); + String bucketName = config.getQcloudBucketName() +"-"+ config.getQcloudAppId(); + PutObjectRequest request = new PutObjectRequest(bucketName, path, inputStream, metadata); + PutObjectResult result = client.putObject(request); + + client.shutdown(); + if(result.getETag() == null){ + throw new RenException(ErrorCode.OSS_UPLOAD_FILE_ERROR, ""); + } + } catch (IOException e) { + throw new RenException(ErrorCode.OSS_UPLOAD_FILE_ERROR, e, ""); + } + + return config.getQcloudDomain() + "/" + path; + } + + @Override + public String uploadSuffix(byte[] data, String suffix) { + return upload(data, getPath(config.getQcloudPrefix(), suffix)); + } + + @Override + public String uploadSuffix(InputStream inputStream, String suffix) { + return upload(inputStream, getPath(config.getQcloudPrefix(), suffix)); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java b/renren-admin/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java new file mode 100644 index 0000000..2361c33 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import com.qiniu.http.Response; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.Region; +import com.qiniu.storage.UploadManager; +import com.qiniu.util.Auth; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; + +/** + * 七牛云存储 + * + * @author Mark sunlightcs@gmail.com + */ +public class QiniuCloudStorageService extends AbstractCloudStorageService { + private UploadManager uploadManager; + private String token; + + public QiniuCloudStorageService(CloudStorageConfig config){ + this.config = config; + + //初始化 + init(); + } + + private void init(){ + uploadManager = new UploadManager(new Configuration(Region.autoRegion())); + token = Auth.create(config.getQiniuAccessKey(), config.getQiniuSecretKey()). + uploadToken(config.getQiniuBucketName()); + + } + + @Override + public String upload(byte[] data, String path) { + try { + Response res = uploadManager.put(data, path, token); + if (!res.isOK()) { + throw new RenException(ErrorCode.OSS_UPLOAD_FILE_ERROR, res.toString()); + } + } catch (Exception e) { + throw new RenException(ErrorCode.OSS_UPLOAD_FILE_ERROR, e, ""); + } + + return config.getQiniuDomain() + "/" + path; + } + + @Override + public String upload(InputStream inputStream, String path) { + try { + byte[] data = IOUtils.toByteArray(inputStream); + return this.upload(data, path); + } catch (IOException e) { + throw new RenException(ErrorCode.OSS_UPLOAD_FILE_ERROR, e, ""); + } + } + + @Override + public String uploadSuffix(byte[] data, String suffix) { + return upload(data, getPath(config.getQiniuPrefix(), suffix)); + } + + @Override + public String uploadSuffix(InputStream inputStream, String suffix) { + return upload(inputStream, getPath(config.getQiniuPrefix(), suffix)); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java b/renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java new file mode 100644 index 0000000..27888c2 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/controller/SysOssController.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.controller; + +import com.google.gson.Gson; +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.page.PageData; +import io.renren.common.utils.Result; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AliyunGroup; +import io.renren.common.validator.group.QcloudGroup; +import io.renren.common.validator.group.QiniuGroup; +import io.renren.modules.oss.cloud.CloudStorageConfig; +import io.renren.modules.oss.cloud.OSSFactory; +import io.renren.modules.oss.entity.SysOssEntity; +import io.renren.modules.oss.service.SysOssService; +import io.renren.modules.sys.service.SysParamsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.io.FilenameUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 文件上传 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("sys/oss") +@Api(tags="文件上传") +public class SysOssController { + @Autowired + private SysOssService sysOssService; + @Autowired + private SysParamsService sysParamsService; + + private final static String KEY = Constant.CLOUD_STORAGE_CONFIG_KEY; + + @GetMapping("page") + @ApiOperation(value = "分页") + @RequiresPermissions("sys:oss:all") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysOssService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("info") + @ApiOperation(value = "云存储配置信息") + @RequiresPermissions("sys:oss:all") + public Result info(){ + CloudStorageConfig config = sysParamsService.getValueObject(KEY, CloudStorageConfig.class); + + return new Result().ok(config); + } + + @PostMapping + @ApiOperation(value = "保存云存储配置信息") + @LogOperation("保存云存储配置信息") + @RequiresPermissions("sys:oss:all") + public Result saveConfig(@RequestBody CloudStorageConfig config){ + //校验类型 + ValidatorUtils.validateEntity(config); + + if(config.getType() == Constant.CloudService.QINIU.getValue()){ + //校验七牛数据 + ValidatorUtils.validateEntity(config, QiniuGroup.class); + }else if(config.getType() == Constant.CloudService.ALIYUN.getValue()){ + //校验阿里云数据 + ValidatorUtils.validateEntity(config, AliyunGroup.class); + }else if(config.getType() == Constant.CloudService.QCLOUD.getValue()){ + //校验腾讯云数据 + ValidatorUtils.validateEntity(config, QcloudGroup.class); + } + + sysParamsService.updateValueByCode(KEY, new Gson().toJson(config)); + + return new Result(); + } + + @PostMapping("upload") + @ApiOperation(value = "上传文件") + @RequiresPermissions("sys:oss:all") + public Result> upload(@RequestParam("file") MultipartFile file) throws Exception { + if (file.isEmpty()) { + return new Result>().error(ErrorCode.UPLOAD_FILE_EMPTY); + } + + //上传文件 + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); + String url = OSSFactory.build().uploadSuffix(file.getBytes(), extension); + + //保存文件信息 + SysOssEntity ossEntity = new SysOssEntity(); + ossEntity.setUrl(url); + ossEntity.setCreateDate(new Date()); + sysOssService.insert(ossEntity); + + Map data = new HashMap<>(1); + data.put("src", url); + + return new Result>().ok(data); + } + + @DeleteMapping + @ApiOperation(value = "删除") + @LogOperation("删除") + @RequiresPermissions("sys:oss:all") + public Result delete(@RequestBody Long[] ids){ + sysOssService.deleteBatchIds(Arrays.asList(ids)); + + return new Result(); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/oss/dao/SysOssDao.java b/renren-admin/src/main/java/io/renren/modules/oss/dao/SysOssDao.java new file mode 100644 index 0000000..0b164b0 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/dao/SysOssDao.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.oss.entity.SysOssEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 文件上传 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysOssDao extends BaseDao { + +} diff --git a/renren-admin/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java b/renren-admin/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java new file mode 100644 index 0000000..af6601a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 文件上传 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_oss") +public class SysOssEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * URL地址 + */ + private String url; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/oss/service/SysOssService.java b/renren-admin/src/main/java/io/renren/modules/oss/service/SysOssService.java new file mode 100644 index 0000000..46736ef --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/service/SysOssService.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.oss.entity.SysOssEntity; + +import java.util.Map; + +/** + * 文件上传 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysOssService extends BaseService { + + PageData page(Map params); +} diff --git a/renren-admin/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java new file mode 100644 index 0000000..04437e7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.modules.oss.dao.SysOssDao; +import io.renren.modules.oss.entity.SysOssEntity; +import io.renren.modules.oss.service.SysOssService; +import org.springframework.stereotype.Service; + +import java.util.Map; + + +@Service +public class SysOssServiceImpl extends BaseServiceImpl implements SysOssService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + new QueryWrapper<>() + ); + return getPageData(page, SysOssEntity.class); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/config/FilterConfig.java b/renren-admin/src/main/java/io/renren/modules/security/config/FilterConfig.java new file mode 100644 index 0000000..5915cb1 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/config/FilterConfig.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.config; + +import io.renren.common.xss.XssFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.DelegatingFilterProxy; + +import javax.servlet.DispatcherType; + +/** + * Filter配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class FilterConfig { + + @Bean + public FilterRegistrationBean shiroFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setFilter(new DelegatingFilterProxy("shiroFilter")); + //该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 + registration.addInitParameter("targetFilterLifecycle", "true"); + registration.setEnabled(true); + registration.setOrder(Integer.MAX_VALUE - 1); + registration.addUrlPatterns("/*"); + return registration; + } + + @Bean + public FilterRegistrationBean xssFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns("/*"); + registration.setName("xssFilter"); + registration.setOrder(Integer.MAX_VALUE); + return registration; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/config/ShiroConfig.java b/renren-admin/src/main/java/io/renren/modules/security/config/ShiroConfig.java new file mode 100644 index 0000000..b4d661c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/config/ShiroConfig.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.config; + +import io.renren.modules.front.interceptor.LoginFilter; +import io.renren.modules.security.oauth2.Oauth2Filter; +import io.renren.modules.security.oauth2.Oauth2Realm; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.session.mgt.SessionManager; +import org.apache.shiro.spring.LifecycleBeanPostProcessor; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.Filter; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Shiro的配置文件 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class ShiroConfig { + + @Bean + public DefaultWebSessionManager sessionManager(){ + DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); + sessionManager.setSessionValidationSchedulerEnabled(false); + sessionManager.setSessionIdUrlRewritingEnabled(false); + + return sessionManager; + } + + @Bean("securityManager") + public SecurityManager securityManager(Oauth2Realm oAuth2Realm, SessionManager sessionManager) { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(oAuth2Realm); + securityManager.setSessionManager(sessionManager); + securityManager.setRememberMeManager(null); + return securityManager; + } + + @Autowired + private LoginFilter loginFilter; + + @Bean("shiroFilter") + public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); + shiroFilter.setSecurityManager(securityManager); + + //oauth过滤 + Map filters = new LinkedHashMap<>(); + filters.put("loginFilter", loginFilter); // 添加自定义过滤器 + filters.put("oauth2", new Oauth2Filter()); + shiroFilter.setFilters(filters); + + Map filterMap = new LinkedHashMap<>(); + filterMap.put("/webjars/**", "anon"); + filterMap.put("/druid/**", "anon"); + filterMap.put("/login", "anon"); + filterMap.put("/swagger/**", "anon"); + filterMap.put("/v2/api-docs", "anon"); + filterMap.put("/doc.html", "anon"); + filterMap.put("/swagger-resources/**", "anon"); + filterMap.put("/captcha", "anon"); + filterMap.put("/favicon.ico", "anon"); + filterMap.put("/", "anon"); + + filterMap.put("/front/**", "loginFilter"); +// filterMap.put("/front/user/sendMsg", "anon"); +// filterMap.put("/front/user/login", "anon"); +// filterMap.put("/front/user/loginout", "anon"); +// filterMap.put("/renren-admin/front/**", "loginFilter"); + + filterMap.put("/**", "oauth2"); + shiroFilter.setFilterChainDefinitionMap(filterMap); + + return shiroFilter; + } + + @Bean("lifecycleBeanPostProcessor") + public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); + advisor.setSecurityManager(securityManager); + return advisor; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/config/WebMvcConfig.java b/renren-admin/src/main/java/io/renren/modules/security/config/WebMvcConfig.java new file mode 100644 index 0000000..df594ef --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/config/WebMvcConfig.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.config; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.renren.common.utils.DateUtils; +import io.renren.modules.front.common.JacksonObjectMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.ResourceHttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.TimeZone; + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowCredentials(true) + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .maxAge(3600); + } + + @Override + public void configureMessageConverters(List> converters) { + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + converters.add(new ResourceHttpMessageConverter()); + converters.add(new AllEncompassingFormHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + converters.add(jackson2HttpMessageConverter()); + } + + @Override + public void extendMessageConverters(List> converters) { + MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); + messageConverter.setObjectMapper(new JacksonObjectMapper()); + converters.add(0, messageConverter); + } + + @Bean + public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + ObjectMapper mapper = new ObjectMapper(); + + //日期格式转换 + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.setDateFormat(new SimpleDateFormat(DateUtils.DATE_TIME_PATTERN)); + mapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); + + //Long类型转String类型 + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(Long.class, ToStringSerializer.instance); + simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); + mapper.registerModule(simpleModule); + + converter.setObjectMapper(mapper); + return converter; + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/controller/LoginController.java b/renren-admin/src/main/java/io/renren/modules/security/controller/LoginController.java new file mode 100644 index 0000000..a64b47d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/controller/LoginController.java @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.controller; + +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.common.utils.IpUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.modules.log.entity.SysLogLoginEntity; +import io.renren.modules.log.enums.LoginOperationEnum; +import io.renren.modules.log.enums.LoginStatusEnum; +import io.renren.modules.log.service.SysLogLoginService; +import io.renren.modules.security.dto.LoginDTO; +import io.renren.modules.security.password.PasswordUtils; +import io.renren.modules.security.service.CaptchaService; +import io.renren.modules.security.service.SysUserTokenService; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dto.SysUserDTO; +import io.renren.modules.sys.enums.UserStatusEnum; +import io.renren.modules.sys.service.SysUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Date; + +/** + * 登录 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@Api(tags="登录管理") +public class LoginController { + @Autowired + private SysUserService sysUserService; + @Autowired + private SysUserTokenService sysUserTokenService; + @Autowired + private CaptchaService captchaService; + @Autowired + private SysLogLoginService sysLogLoginService; + + @GetMapping("captcha") + @ApiOperation(value = "验证码", produces="application/octet-stream") + @ApiImplicitParam(paramType = "query", dataType="string", name = "uuid", required = true) + public void captcha(HttpServletResponse response, String uuid)throws IOException { + //uuid不能为空 + AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL); + + //生成验证码 + captchaService.create(response, uuid); + } + + @PostMapping("login") + @ApiOperation(value = "登录") + public Result login(HttpServletRequest request, @RequestBody LoginDTO login) { + //效验数据 + ValidatorUtils.validateEntity(login); + + //验证码是否正确 + boolean flag = captchaService.validate(login.getUuid(), login.getCaptcha()); + if(!flag){ + return new Result().error(ErrorCode.CAPTCHA_ERROR); + } + + //用户信息 + SysUserDTO user = sysUserService.getByUsername(login.getUsername()); + + SysLogLoginEntity log = new SysLogLoginEntity(); + log.setOperation(LoginOperationEnum.LOGIN.value()); + log.setCreateDate(new Date()); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + + //用户不存在 + if(user == null){ + log.setStatus(LoginStatusEnum.FAIL.value()); + log.setCreatorName(login.getUsername()); + sysLogLoginService.save(log); + + throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR); + } + + //密码错误 + if(!PasswordUtils.matches(login.getPassword(), user.getPassword())){ + log.setStatus(LoginStatusEnum.FAIL.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + sysLogLoginService.save(log); + + throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR); + } + + //账号停用 + if(user.getStatus() == UserStatusEnum.DISABLE.value()){ + log.setStatus(LoginStatusEnum.LOCK.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + sysLogLoginService.save(log); + + throw new RenException(ErrorCode.ACCOUNT_DISABLE); + } + + //登录成功 + log.setStatus(LoginStatusEnum.SUCCESS.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + sysLogLoginService.save(log); + + return sysUserTokenService.createToken(user.getId()); + } + + @PostMapping("logout") + @ApiOperation(value = "退出") + public Result logout(HttpServletRequest request) { + UserDetail user = SecurityUser.getUser(); + + //退出 + sysUserTokenService.logout(user.getId()); + + //用户信息 + SysLogLoginEntity log = new SysLogLoginEntity(); + log.setOperation(LoginOperationEnum.LOGOUT.value()); + log.setIp(IpUtils.getIpAddr(request)); + log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT)); + log.setIp(IpUtils.getIpAddr(request)); + log.setStatus(LoginStatusEnum.SUCCESS.value()); + log.setCreator(user.getId()); + log.setCreatorName(user.getUsername()); + log.setCreateDate(new Date()); + sysLogLoginService.save(log); + + return new Result(); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/dao/SysUserTokenDao.java b/renren-admin/src/main/java/io/renren/modules/security/dao/SysUserTokenDao.java new file mode 100644 index 0000000..154b130 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/dao/SysUserTokenDao.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.security.entity.SysUserTokenEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 系统用户Token + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserTokenDao extends BaseDao { + + SysUserTokenEntity getByToken(String token); + + SysUserTokenEntity getByUserId(Long userId); + + void updateToken(@Param("userId") Long userId, @Param("token") String token); +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/dto/LoginDTO.java b/renren-admin/src/main/java/io/renren/modules/security/dto/LoginDTO.java new file mode 100644 index 0000000..608fc9b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/dto/LoginDTO.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 登录表单 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "登录表单") +public class LoginDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "用户名", required = true) + @NotBlank(message="{sysuser.username.require}") + private String username; + + @ApiModelProperty(value = "密码") + @NotBlank(message="{sysuser.password.require}") + private String password; + + @ApiModelProperty(value = "验证码") + @NotBlank(message="{sysuser.captcha.require}") + private String captcha; + + @ApiModelProperty(value = "唯一标识") + @NotBlank(message="{sysuser.uuid.require}") + private String uuid; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/entity/SysUserTokenEntity.java b/renren-admin/src/main/java/io/renren/modules/security/entity/SysUserTokenEntity.java new file mode 100644 index 0000000..3002c8e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/entity/SysUserTokenEntity.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.entity; + +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 lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 系统用户Token + */ +@Data +@TableName("sys_user_token") +public class SysUserTokenEntity implements Serializable { + private static final long serialVersionUID = 1L; + /** + * id + */ + @TableId + private Long id; + /** + * 用户ID + */ + private Long userId; + /** + * 用户token + */ + private String token; + /** + * 过期时间 + */ + private Date expireDate; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private Date createDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Filter.java b/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Filter.java new file mode 100644 index 0000000..5836068 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Filter.java @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.oauth2; + +import com.google.gson.Gson; +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.utils.HttpContextUtils; +import io.renren.common.utils.Result; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.web.filter.authc.AuthenticatingFilter; +import org.springframework.web.bind.annotation.RequestMethod; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * oauth2过滤器 + * + * @author Mark sunlightcs@gmail.com + */ +public class Oauth2Filter extends AuthenticatingFilter { + + @Override + protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token + String token = getRequestToken((HttpServletRequest) request); + + if(StringUtils.isBlank(token)){ + return null; + } + + return new Oauth2Token(token); + } + + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { + if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){ + return true; + } + + return false; + } + + @Override + protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token,如果token不存在,直接返回401 + String token = getRequestToken((HttpServletRequest) request); + if(StringUtils.isBlank(token)){ + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setContentType("application/json;charset=utf-8"); + httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); + + String json = new Gson().toJson(new Result().error(ErrorCode.UNAUTHORIZED)); + + httpResponse.getWriter().print(json); + + return false; + } + return executeLogin(request, response); + } + + @Override + protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setContentType("application/json;charset=utf-8"); + httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); + try { + //处理登录失败的异常 + Throwable throwable = e.getCause() == null ? e : e.getCause(); + Result r = new Result().error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage()); + + String json = new Gson().toJson(r); + httpResponse.getWriter().print(json); + } catch (IOException e1) { + + } + + return false; + } + + /** + * 获取请求的token + */ + private String getRequestToken(HttpServletRequest httpRequest){ + //从header中获取token + String token = httpRequest.getHeader(Constant.TOKEN_HEADER); + + //如果header中不存在token,则从参数中获取token + if(StringUtils.isBlank(token)){ + token = httpRequest.getParameter(Constant.TOKEN_HEADER); + } + + return token; + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Realm.java b/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Realm.java new file mode 100644 index 0000000..12ccf74 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Realm.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.oauth2; + +import io.renren.common.exception.ErrorCode; +import io.renren.common.utils.ConvertUtils; +import io.renren.common.utils.MessageUtils; +import io.renren.modules.security.entity.SysUserTokenEntity; +import io.renren.modules.security.service.ShiroService; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.entity.SysUserEntity; +import org.apache.shiro.authc.*; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Set; + +/** + * 认证 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class Oauth2Realm extends AuthorizingRealm { + @Autowired + private ShiroService shiroService; + + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof Oauth2Token; + } + + /** + * 授权(验证权限时调用) + */ + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + UserDetail user = (UserDetail)principals.getPrimaryPrincipal(); + + //用户权限列表 + Set permsSet = shiroService.getUserPermissions(user); + + SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); + info.setStringPermissions(permsSet); + return info; + } + + /** + * 认证(登录时调用) + */ + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { + String accessToken = (String) token.getPrincipal(); + + //根据accessToken,查询用户信息 + SysUserTokenEntity tokenEntity = shiroService.getByToken(accessToken); + //token失效 + if(tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){ + throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID)); + } + + //查询用户信息 + SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId()); + + //转换成UserDetail对象 + UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class); + + //获取用户对应的部门数据权限 + List deptIdList = shiroService.getDataScopeList(userDetail.getId()); + userDetail.setDeptIdList(deptIdList); + + //账号锁定 + if(userDetail.getStatus() == 0){ + throw new LockedAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_LOCK)); + } + + SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDetail, accessToken, getName()); + return info; + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Token.java b/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Token.java new file mode 100644 index 0000000..f6be31d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/oauth2/Oauth2Token.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.oauth2; + +import org.apache.shiro.authc.AuthenticationToken; + +/** + * token + * + * @author Mark sunlightcs@gmail.com + */ +public class Oauth2Token implements AuthenticationToken { + private String token; + + public Oauth2Token(String token){ + this.token = token; + } + + @Override + public String getPrincipal() { + return token; + } + + @Override + public Object getCredentials() { + return token; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/oauth2/TokenGenerator.java b/renren-admin/src/main/java/io/renren/modules/security/oauth2/TokenGenerator.java new file mode 100644 index 0000000..13d0014 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/oauth2/TokenGenerator.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.oauth2; + +import io.renren.common.exception.RenException; + +import java.security.MessageDigest; +import java.util.UUID; + +/** + * 生成token + * + * @author Mark sunlightcs@gmail.com + */ +public class TokenGenerator { + + public static String generateValue() { + return generateValue(UUID.randomUUID().toString()); + } + + private static final char[] HEX_CODE = "0123456789abcdef".toCharArray(); + + public static String toHexString(byte[] data) { + if(data == null) { + return null; + } + StringBuilder r = new StringBuilder(data.length*2); + for ( byte b : data) { + r.append(HEX_CODE[(b >> 4) & 0xF]); + r.append(HEX_CODE[(b & 0xF)]); + } + return r.toString(); + } + + public static String generateValue(String param) { + try { + MessageDigest algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(param.getBytes()); + byte[] messageDigest = algorithm.digest(); + return toHexString(messageDigest); + } catch (Exception e) { + throw new RenException("token invalid", e); + } + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/password/BCrypt.java b/renren-admin/src/main/java/io/renren/modules/security/password/BCrypt.java new file mode 100644 index 0000000..1383c38 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/password/BCrypt.java @@ -0,0 +1,662 @@ +package io.renren.modules.security.password; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.security.SecureRandom; + +/** + * BCrypt implements OpenBSD-style Blowfish password hashing using the scheme described in + * "A Future-Adaptable Password Scheme" by Niels Provos and David Mazieres. + *

+ * This password hashing system tries to thwart off-line password cracking using a + * computationally-intensive hashing algorithm, based on Bruce Schneier's Blowfish cipher. + * The work factor of the algorithm is parameterised, so it can be increased as computers + * get faster. + *

+ * Usage is really simple. To hash a password for the first time, call the hashpw method + * with a random salt, like this: + *

+ * + * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
+ *
+ *

+ * To check whether a plaintext password matches one that has been hashed previously, use + * the checkpw method: + *

+ * + * if (BCrypt.checkpw(candidate_password, stored_hash))
+ *     System.out.println("It matches");
+ * else
+ *     System.out.println("It does not match");
+ *
+ *

+ * The gensalt() method takes an optional parameter (log_rounds) that determines the + * computational complexity of the hashing: + *

+ * + * String strong_salt = BCrypt.gensalt(10)
+ * String stronger_salt = BCrypt.gensalt(12)
+ *
+ *

+ * The amount of work increases exponentially (2**log_rounds), so each increment is twice + * as much work. The default log_rounds is 10, and the valid range is 4 to 31. + * + * @author Damien Miller + */ +public class BCrypt { + // BCrypt parameters + + private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10; + private static final int BCRYPT_SALT_LEN = 16; + // Blowfish parameters + private static final int BLOWFISH_NUM_ROUNDS = 16; + // Initial contents of key schedule + private static final int P_orig[] = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, + 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b }; + private static final int S_orig[] = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, + 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, + 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, + 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, + 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, + 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, + 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, + 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, + 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, + 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, + 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, + 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, + 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, + 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, + 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, + 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, + 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, + 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, + 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, + 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, + 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, + 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, + 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, + 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, + 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, + 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, + 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, + 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, + 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, + 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, + 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, + 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, + 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, + 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, + 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, + 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, + 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, + 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, + 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, + 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, + 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, + 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, + 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, + 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, + 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, + 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, + 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, + 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, + 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, + 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, + 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, + 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, + 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, + 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, + 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, + 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, + 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, + 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, + 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, + 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, + 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, + 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, + 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, + 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, + 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, + 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, + 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, + 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, + 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, + 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, + 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, + 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, + 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, + 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, + 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, + 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, + 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, + 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, + 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, + 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, + 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, + 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, + 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, + 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, + 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, + 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 }; + // bcrypt IV: "OrpheanBeholderScryDoubt" + static private final int bf_crypt_ciphertext[] = { 0x4f727068, 0x65616e42, + 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274 }; + // Table for Base64 encoding + static private final char base64_code[] = { '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', + 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + // Table for Base64 decoding + static private final byte index_64[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + -1, -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1 }; + static final int MIN_LOG_ROUNDS = 4; + static final int MAX_LOG_ROUNDS = 31; + // Expanded Blowfish key + private int P[]; + private int S[]; + + /** + * Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note + * that this is not compatible with the standard MIME-base64 + * encoding. + * + * @param d the byte array to encode + * @param len the number of bytes to encode + * @param rs the destination buffer for the base64-encoded string + * @exception IllegalArgumentException if the length is invalid + */ + static void encode_base64(byte d[], int len, StringBuilder rs) + throws IllegalArgumentException { + int off = 0; + int c1, c2; + + if (len <= 0 || len > d.length) { + throw new IllegalArgumentException("Invalid len"); + } + + while (off < len) { + c1 = d[off++] & 0xff; + rs.append(base64_code[(c1 >> 2) & 0x3f]); + c1 = (c1 & 0x03) << 4; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 4) & 0x0f; + rs.append(base64_code[c1 & 0x3f]); + c1 = (c2 & 0x0f) << 2; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 6) & 0x03; + rs.append(base64_code[c1 & 0x3f]); + rs.append(base64_code[c2 & 0x3f]); + } + } + + /** + * Look up the 3 bits base64-encoded by the specified character, range-checking + * against conversion table + * @param x the base64-encoded value + * @return the decoded value of x + */ + private static byte char64(char x) { + if (x > index_64.length) { + return -1; + } + return index_64[x]; + } + + /** + * Decode a string encoded using bcrypt's base64 scheme to a byte array. Note that + * this is *not* compatible with the standard MIME-base64 encoding. + * @param s the string to decode + * @param maxolen the maximum number of bytes to decode + * @return an array containing the decoded bytes + * @throws IllegalArgumentException if maxolen is invalid + */ + static byte[] decode_base64(String s, int maxolen) throws IllegalArgumentException { + ByteArrayOutputStream out = new ByteArrayOutputStream(maxolen); + int off = 0, slen = s.length(), olen = 0; + byte c1, c2, c3, c4, o; + + if (maxolen <= 0) { + throw new IllegalArgumentException("Invalid maxolen"); + } + + while (off < slen - 1 && olen < maxolen) { + c1 = char64(s.charAt(off++)); + c2 = char64(s.charAt(off++)); + if (c1 == -1 || c2 == -1) { + break; + } + o = (byte) (c1 << 2); + o |= (c2 & 0x30) >> 4; + out.write(o); + if (++olen >= maxolen || off >= slen) { + break; + } + c3 = char64(s.charAt(off++)); + if (c3 == -1) { + break; + } + o = (byte) ((c2 & 0x0f) << 4); + o |= (c3 & 0x3c) >> 2; + out.write(o); + if (++olen >= maxolen || off >= slen) { + break; + } + c4 = char64(s.charAt(off++)); + o = (byte) ((c3 & 0x03) << 6); + o |= c4; + out.write(o); + ++olen; + } + + return out.toByteArray(); + } + + /** + * Blowfish encipher a single 64-bit block encoded as two 32-bit halves + * @param lr an array containing the two 32-bit half blocks + * @param off the position in the array of the blocks + */ + private final void encipher(int lr[], int off) { + int i, n, l = lr[off], r = lr[off + 1]; + + l ^= P[0]; + for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) { + // Feistel substitution on left word + n = S[(l >> 24) & 0xff]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[++i]; + + // Feistel substitution on right word + n = S[(r >> 24) & 0xff]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[++i]; + } + lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; + lr[off + 1] = l; + } + + /** + * Cycically extract a word of key material + * @param data the string to extract the data from + * @param offp a "pointer" (as a one-entry array) to the current offset into data + * @return the next word of material from data + */ + private static int streamtoword(byte data[], int offp[]) { + int i; + int word = 0; + int off = offp[0]; + + for (i = 0; i < 4; i++) { + word = (word << 8) | (data[off] & 0xff); + off = (off + 1) % data.length; + } + + offp[0] = off; + return word; + } + + /** + * Initialise the Blowfish key schedule + */ + private void init_key() { + P = (int[]) P_orig.clone(); + S = (int[]) S_orig.clone(); + } + + /** + * Key the Blowfish cipher + * @param key an array containing the key + */ + private void key(byte key[]) { + int i; + int koffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) { + P[i] = P[i] ^ streamtoword(key, koffp); + } + + for (i = 0; i < plen; i += 2) { + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + /** + * Perform the "enhanced key schedule" step described by Provos and Mazieres in + * "A Future-Adaptable Password Scheme" http://www.openbsd.org/papers/bcrypt-paper.ps + * @param data salt information + * @param key password information + */ + private void ekskey(byte data[], byte key[]) { + int i; + int koffp[] = { 0 }, doffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) { + P[i] = P[i] ^ streamtoword(key, koffp); + } + + for (i = 0; i < plen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + static long roundsForLogRounds(int log_rounds) { + if (log_rounds < 4 || log_rounds > 31) { + throw new IllegalArgumentException("Bad number of rounds"); + } + return 1L << log_rounds; + } + + /** + * Perform the central password hashing step in the bcrypt scheme + * @param password the password to hash + * @param salt the binary salt to hash with the password + * @param log_rounds the binary logarithm of the number of rounds of hashing to apply + * @return an array containing the binary hashed password + */ + private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) { + int cdata[] = (int[]) bf_crypt_ciphertext.clone(); + int clen = cdata.length; + byte ret[]; + + long rounds = roundsForLogRounds(log_rounds); + + init_key(); + ekskey(salt, password); + for (long i = 0; i < rounds; i++) { + key(password); + key(salt); + } + + for (int i = 0; i < 64; i++) { + for (int j = 0; j < (clen >> 1); j++) { + encipher(cdata, j << 1); + } + } + + ret = new byte[clen * 4]; + for (int i = 0, j = 0; i < clen; i++) { + ret[j++] = (byte) ((cdata[i] >> 24) & 0xff); + ret[j++] = (byte) ((cdata[i] >> 16) & 0xff); + ret[j++] = (byte) ((cdata[i] >> 8) & 0xff); + ret[j++] = (byte) (cdata[i] & 0xff); + } + return ret; + } + + /** + * Hash a password using the OpenBSD bcrypt scheme + * @param password the password to hash + * @param salt the salt to hash with (perhaps generated using BCrypt.gensalt) + * @return the hashed password + * @throws IllegalArgumentException if invalid salt is passed + */ + public static String hashpw(String password, String salt) throws IllegalArgumentException { + BCrypt B; + String real_salt; + byte passwordb[], saltb[], hashed[]; + char minor = (char) 0; + int rounds, off = 0; + StringBuilder rs = new StringBuilder(); + + if (salt == null) { + throw new IllegalArgumentException("salt cannot be null"); + } + + int saltLength = salt.length(); + + if (saltLength < 28) { + throw new IllegalArgumentException("Invalid salt"); + } + + if (salt.charAt(0) != '$' || salt.charAt(1) != '2') { + throw new IllegalArgumentException("Invalid salt version"); + } + if (salt.charAt(2) == '$') { + off = 3; + } + else { + minor = salt.charAt(2); + if (minor != 'a' || salt.charAt(3) != '$') { + throw new IllegalArgumentException("Invalid salt revision"); + } + off = 4; + } + + if (saltLength - off < 25) { + throw new IllegalArgumentException("Invalid salt"); + } + + // Extract number of rounds + if (salt.charAt(off + 2) > '$') { + throw new IllegalArgumentException("Missing salt rounds"); + } + rounds = Integer.parseInt(salt.substring(off, off + 2)); + + real_salt = salt.substring(off + 3, off + 25); + try { + passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8"); + } + catch (UnsupportedEncodingException uee) { + throw new AssertionError("UTF-8 is not supported"); + } + + saltb = decode_base64(real_salt, BCRYPT_SALT_LEN); + + B = new BCrypt(); + hashed = B.crypt_raw(passwordb, saltb, rounds); + + rs.append("$2"); + if (minor >= 'a') { + rs.append(minor); + } + rs.append("$"); + if (rounds < 10) { + rs.append("0"); + } + rs.append(rounds); + rs.append("$"); + encode_base64(saltb, saltb.length, rs); + encode_base64(hashed, bf_crypt_ciphertext.length * 4 - 1, rs); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of hashing to apply - the work + * factor therefore increases as 2**log_rounds. Minimum 4, maximum 31. + * @param random an instance of SecureRandom to use + * @return an encoded salt value + */ + public static String gensalt(int log_rounds, SecureRandom random) { + if (log_rounds < MIN_LOG_ROUNDS || log_rounds > MAX_LOG_ROUNDS) { + throw new IllegalArgumentException("Bad number of rounds"); + } + StringBuilder rs = new StringBuilder(); + byte rnd[] = new byte[BCRYPT_SALT_LEN]; + + random.nextBytes(rnd); + + rs.append("$2a$"); + if (log_rounds < 10) { + rs.append("0"); + } + rs.append(log_rounds); + rs.append("$"); + encode_base64(rnd, rnd.length, rs); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of hashing to apply - the work + * factor therefore increases as 2**log_rounds. Minimum 4, maximum 31. + * @return an encoded salt value + */ + public static String gensalt(int log_rounds) { + return gensalt(log_rounds, new SecureRandom()); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method, selecting a reasonable + * default for the number of hashing rounds to apply + * @return an encoded salt value + */ + public static String gensalt() { + return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS); + } + + /** + * Check that a plaintext password matches a previously hashed one + * @param plaintext the plaintext password to verify + * @param hashed the previously-hashed password + * @return true if the passwords match, false otherwise + */ + public static boolean checkpw(String plaintext, String hashed) { + return equalsNoEarlyReturn(hashed, hashpw(plaintext, hashed)); + } + + static boolean equalsNoEarlyReturn(String a, String b) { + char[] caa = a.toCharArray(); + char[] cab = b.toCharArray(); + + if (caa.length != cab.length) { + return false; + } + + byte ret = 0; + for (int i = 0; i < caa.length; i++) { + ret |= caa[i] ^ cab[i]; + } + return ret == 0; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/password/BCryptPasswordEncoder.java b/renren-admin/src/main/java/io/renren/modules/security/password/BCryptPasswordEncoder.java new file mode 100644 index 0000000..d27be66 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/password/BCryptPasswordEncoder.java @@ -0,0 +1,82 @@ +package io.renren.modules.security.password; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.security.SecureRandom; +import java.util.regex.Pattern; + +/** + * Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients + * can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom + * instance. The larger the strength parameter the more work will have to be done + * (exponentially) to hash the passwords. The default value is 10. + * + * @author Dave Syer + * + */ +public class BCryptPasswordEncoder implements PasswordEncoder { + private Pattern BCRYPT_PATTERN = Pattern + .compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}"); + private final Log logger = LogFactory.getLog(getClass()); + + private final int strength; + + private final SecureRandom random; + + public BCryptPasswordEncoder() { + this(-1); + } + + /** + * @param strength the log rounds to use, between 4 and 31 + */ + public BCryptPasswordEncoder(int strength) { + this(strength, null); + } + + /** + * @param strength the log rounds to use, between 4 and 31 + * @param random the secure random instance to use + * + */ + public BCryptPasswordEncoder(int strength, SecureRandom random) { + if (strength != -1 && (strength < BCrypt.MIN_LOG_ROUNDS || strength > BCrypt.MAX_LOG_ROUNDS)) { + throw new IllegalArgumentException("Bad strength"); + } + this.strength = strength; + this.random = random; + } + + @Override + public String encode(CharSequence rawPassword) { + String salt; + if (strength > 0) { + if (random != null) { + salt = BCrypt.gensalt(strength, random); + } + else { + salt = BCrypt.gensalt(strength); + } + } + else { + salt = BCrypt.gensalt(); + } + return BCrypt.hashpw(rawPassword.toString(), salt); + } + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + if (encodedPassword == null || encodedPassword.length() == 0) { + logger.warn("Empty encoded password"); + return false; + } + + if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) { + logger.warn("Encoded password does not look like BCrypt"); + return false; + } + + return BCrypt.checkpw(rawPassword.toString(), encodedPassword); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/password/PasswordEncoder.java b/renren-admin/src/main/java/io/renren/modules/security/password/PasswordEncoder.java new file mode 100644 index 0000000..3b746e6 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/password/PasswordEncoder.java @@ -0,0 +1,30 @@ +package io.renren.modules.security.password; + +/** + * Service interface for encoding passwords. + * + * The preferred implementation is {@code BCryptPasswordEncoder}. + * + * @author Keith Donald + */ +public interface PasswordEncoder { + + /** + * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or + * greater hash combined with an 8-byte or greater randomly generated salt. + */ + String encode(CharSequence rawPassword); + + /** + * Verify the encoded password obtained from storage matches the submitted raw + * password after it too is encoded. Returns true if the passwords match, false if + * they do not. The stored password itself is never decoded. + * + * @param rawPassword the raw password to encode and match + * @param encodedPassword the encoded password from storage to compare with + * @return true if the raw password, after encoding, matches the encoded password from + * storage + */ + boolean matches(CharSequence rawPassword, String encodedPassword); + +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/password/PasswordUtils.java b/renren-admin/src/main/java/io/renren/modules/security/password/PasswordUtils.java new file mode 100644 index 0000000..be12fa6 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/password/PasswordUtils.java @@ -0,0 +1,58 @@ +/** + * Copyright 2018 人人开源 https://www.renren.io + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package io.renren.modules.security.password; + +/** + * 密码工具类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class PasswordUtils { + private static PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + + /** + * 加密 + * @param str 字符串 + * @return 返回加密字符串 + */ + public static String encode(String str){ + return passwordEncoder.encode(str); + } + + + /** + * 比较密码是否相等 + * @param str 明文密码 + * @param password 加密后密码 + * @return true:成功 false:失败 + */ + public static boolean matches(String str, String password){ + return passwordEncoder.matches(str, password); + } + + + public static void main(String[] args) { + String str = "admin"; + String password = encode(str); + + System.out.println(password); + System.out.println(matches(str, password)); + } + +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/service/CaptchaService.java b/renren-admin/src/main/java/io/renren/modules/security/service/CaptchaService.java new file mode 100644 index 0000000..e660f75 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/service/CaptchaService.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.service; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 验证码 + * + * @author Mark sunlightcs@gmail.com + */ +public interface CaptchaService { + + /** + * 图片验证码 + */ + void create(HttpServletResponse response, String uuid) throws IOException; + + /** + * 验证码效验 + * @param uuid uuid + * @param code 验证码 + * @return true:成功 false:失败 + */ + boolean validate(String uuid, String code); +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/service/ShiroService.java b/renren-admin/src/main/java/io/renren/modules/security/service/ShiroService.java new file mode 100644 index 0000000..5beca6e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/service/ShiroService.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.service; + +import io.renren.modules.security.entity.SysUserTokenEntity; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.entity.SysUserEntity; + +import java.util.List; +import java.util.Set; + +/** + * shiro相关接口 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ShiroService { + /** + * 获取用户权限列表 + */ + Set getUserPermissions(UserDetail user); + + SysUserTokenEntity getByToken(String token); + + /** + * 根据用户ID,查询用户 + * @param userId + */ + SysUserEntity getUser(Long userId); + + /** + * 获取用户对应的部门数据权限 + * @param userId 用户ID + * @return 返回部门ID列表 + */ + List getDataScopeList(Long userId); +} diff --git a/renren-admin/src/main/java/io/renren/modules/security/service/SysUserTokenService.java b/renren-admin/src/main/java/io/renren/modules/security/service/SysUserTokenService.java new file mode 100644 index 0000000..881493c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/service/SysUserTokenService.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.service; + +import io.renren.common.service.BaseService; +import io.renren.common.utils.Result; +import io.renren.modules.security.entity.SysUserTokenEntity; + +/** + * 用户Token + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysUserTokenService extends BaseService { + + /** + * 生成token + * @param userId 用户ID + */ + Result createToken(Long userId); + + /** + * 退出,修改token值 + * @param userId 用户ID + */ + void logout(Long userId); + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/service/impl/CaptchaServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/security/service/impl/CaptchaServiceImpl.java new file mode 100644 index 0000000..9094f91 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/service/impl/CaptchaServiceImpl.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.service.impl; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.wf.captcha.SpecCaptcha; +import com.wf.captcha.base.Captcha; +import io.renren.common.redis.RedisKeys; +import io.renren.common.redis.RedisUtils; +import io.renren.modules.security.service.CaptchaService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * 验证码 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class CaptchaServiceImpl implements CaptchaService { + @Autowired + private RedisUtils redisUtils; + @Value("${renren.redis.open: false}") + private boolean open; + /** + * Local Cache 5分钟过期 + */ + Cache localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build(); + + @Override + public void create(HttpServletResponse response, String uuid) throws IOException { + response.setContentType("image/gif"); + response.setHeader("Pragma", "No-cache"); + response.setHeader("Cache-Control", "no-cache"); + response.setDateHeader("Expires", 0); + + //生成验证码 + SpecCaptcha captcha = new SpecCaptcha(150, 40); + captcha.setLen(5); + captcha.setCharType(Captcha.TYPE_DEFAULT); + captcha.out(response.getOutputStream()); + + //保存到缓存 + setCache(uuid, captcha.text()); + } + + @Override + public boolean validate(String uuid, String code) { + //获取验证码 + String captcha = getCache(uuid); + + //效验成功 + if(code.equalsIgnoreCase(captcha)){ + return true; + } + + return false; + } + + private void setCache(String key, String value){ + if(open){ + key = RedisKeys.getCaptchaKey(key); + redisUtils.set(key, value, 300); + }else{ + localCache.put(key, value); + } + } + + private String getCache(String key){ + if(open){ + key = RedisKeys.getCaptchaKey(key); + String captcha = (String)redisUtils.get(key); + //删除验证码 + if(captcha != null){ + redisUtils.delete(key); + } + + return captcha; + } + + String captcha = localCache.getIfPresent(key); + //删除验证码 + if(captcha != null){ + localCache.invalidate(key); + } + return captcha; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/service/impl/ShiroServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/security/service/impl/ShiroServiceImpl.java new file mode 100644 index 0000000..8c5e620 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/service/impl/ShiroServiceImpl.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.service.impl; + +import io.renren.modules.security.dao.SysUserTokenDao; +import io.renren.modules.security.entity.SysUserTokenEntity; +import io.renren.modules.security.service.ShiroService; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dao.SysMenuDao; +import io.renren.modules.sys.dao.SysRoleDataScopeDao; +import io.renren.modules.sys.dao.SysUserDao; +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.enums.SuperAdminEnum; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Service +public class ShiroServiceImpl implements ShiroService { + @Autowired + private SysMenuDao sysMenuDao; + @Autowired + private SysUserDao sysUserDao; + @Autowired + private SysUserTokenDao sysUserTokenDao; + @Autowired + private SysRoleDataScopeDao sysRoleDataScopeDao; + + @Override + public Set getUserPermissions(UserDetail user) { + //系统管理员,拥有最高权限 + List permissionsList; + if(user.getSuperAdmin() == SuperAdminEnum.YES.value()) { + permissionsList = sysMenuDao.getPermissionsList(); + }else{ + permissionsList = sysMenuDao.getUserPermissionsList(user.getId()); + } + + //用户权限列表 + Set permsSet = new HashSet<>(); + for(String permissions : permissionsList){ + if(StringUtils.isBlank(permissions)){ + continue; + } + permsSet.addAll(Arrays.asList(permissions.trim().split(","))); + } + + return permsSet; + } + + @Override + public SysUserTokenEntity getByToken(String token) { + return sysUserTokenDao.getByToken(token); + } + + @Override + public SysUserEntity getUser(Long userId) { + return sysUserDao.selectById(userId); + } + + @Override + public List getDataScopeList(Long userId) { + return sysRoleDataScopeDao.getDataScopeList(userId); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/service/impl/SysUserTokenServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/security/service/impl/SysUserTokenServiceImpl.java new file mode 100644 index 0000000..3911f94 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/service/impl/SysUserTokenServiceImpl.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.service.impl; + +import io.renren.common.constant.Constant; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.Result; +import io.renren.modules.security.dao.SysUserTokenDao; +import io.renren.modules.security.entity.SysUserTokenEntity; +import io.renren.modules.security.oauth2.TokenGenerator; +import io.renren.modules.security.service.SysUserTokenService; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Service +public class SysUserTokenServiceImpl extends BaseServiceImpl implements SysUserTokenService { + /** + * 12小时后过期 + */ + private final static int EXPIRE = 3600 * 12; + + @Override + public Result createToken(Long userId) { + //用户token + String token; + + //当前时间 + Date now = new Date(); + //过期时间 + Date expireTime = new Date(now.getTime() + EXPIRE * 1000); + + //判断是否生成过token + SysUserTokenEntity tokenEntity = baseDao.getByUserId(userId); + if(tokenEntity == null){ + //生成一个token + token = TokenGenerator.generateValue(); + + tokenEntity = new SysUserTokenEntity(); + tokenEntity.setUserId(userId); + tokenEntity.setToken(token); + tokenEntity.setUpdateDate(now); + tokenEntity.setExpireDate(expireTime); + + //保存token + this.insert(tokenEntity); + }else{ + //判断token是否过期 + if(tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){ + //token过期,重新生成token + token = TokenGenerator.generateValue(); + }else { + token = tokenEntity.getToken(); + } + + tokenEntity.setToken(token); + tokenEntity.setUpdateDate(now); + tokenEntity.setExpireDate(expireTime); + + //更新token + this.updateById(tokenEntity); + } + + Map map = new HashMap<>(2); + map.put(Constant.TOKEN_HEADER, token); + map.put("expire", EXPIRE); + return new Result().ok(map); + } + + @Override + public void logout(Long userId) { + //生成一个token + String token = TokenGenerator.generateValue(); + + //修改token + baseDao.updateToken(userId, token); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/user/SecurityUser.java b/renren-admin/src/main/java/io/renren/modules/security/user/SecurityUser.java new file mode 100644 index 0000000..2336337 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/user/SecurityUser.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.user; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + +/** + * 用户 + * + * @author Mark sunlightcs@gmail.com + */ +public class SecurityUser { + + public static Subject getSubject() { + try { + return SecurityUtils.getSubject(); + }catch (Exception e){ + return null; + } + } + + /** + * 获取用户信息 + */ + public static UserDetail getUser() { + Subject subject = getSubject(); + if(subject == null){ + return new UserDetail(); + } + + UserDetail user = (UserDetail)subject.getPrincipal(); + if(user == null){ + return new UserDetail(); + } + + return user; + } + + /** + * 获取用户ID + */ + public static Long getUserId() { + return getUser().getId(); + } + + /** + * 获取部门ID + */ + public static Long getDeptId() { + return getUser().getDeptId(); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/security/user/UserDetail.java b/renren-admin/src/main/java/io/renren/modules/security/user/UserDetail.java new file mode 100644 index 0000000..aee9cf5 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/security/user/UserDetail.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.security.user; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 登录用户信息 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public class UserDetail implements Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + private String username; + private String realName; + private String headUrl; + private Integer gender; + private String email; + private String mobile; + private Long deptId; + private String password; + private Integer status; + private Integer superAdmin; + /** + * 部门数据权限 + */ + private List deptIdList; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/IndexController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/IndexController.java new file mode 100644 index 0000000..18fb248 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/IndexController.java @@ -0,0 +1,20 @@ +package io.renren.modules.sys.controller; + +import io.renren.common.utils.Result; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 首页提示 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +public class IndexController { + + @GetMapping("/") + public Result index(){ + String tips = "你好,renren-admin已启动,请启动renren-ui,才能访问页面!"; + return new Result().ok(tips); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDeptController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDeptController.java new file mode 100644 index 0000000..c2e944d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDeptController.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.sys.dto.SysDeptDTO; +import io.renren.modules.sys.service.SysDeptService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/dept") +@Api(tags="部门管理") +public class SysDeptController { + @Autowired + private SysDeptService sysDeptService; + + @GetMapping("list") + @ApiOperation("列表") + @RequiresPermissions("sys:dept:list") + public Result> list(){ + List list = sysDeptService.list(new HashMap<>(1)); + + return new Result>().ok(list); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:dept:info") + public Result get(@PathVariable("id") Long id){ + SysDeptDTO data = sysDeptService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:dept:save") + public Result save(@RequestBody SysDeptDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysDeptService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:dept:update") + public Result update(@RequestBody SysDeptDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysDeptService.update(dto); + + return new Result(); + } + + @DeleteMapping("{id}") + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:dept:delete") + public Result delete(@PathVariable("id") Long id){ + //效验数据 + AssertUtils.isNull(id, "id"); + + sysDeptService.delete(id); + + return new Result(); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictDataController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictDataController.java new file mode 100644 index 0000000..d2310cc --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictDataController.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.sys.dto.SysDictDataDTO; +import io.renren.modules.sys.service.SysDictDataService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.Map; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("sys/dict/data") +@Api(tags="字典数据") +public class SysDictDataController { + @Autowired + private SysDictDataService sysDictDataService; + + @GetMapping("page") + @ApiOperation("字典数据") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "dictLabel", value = "字典标签", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "dictValue", value = "字典值", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:dict:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + //字典类型 + PageData page = sysDictDataService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:dict:info") + public Result get(@PathVariable("id") Long id){ + SysDictDataDTO data = sysDictDataService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:dict:save") + public Result save(@RequestBody SysDictDataDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + sysDictDataService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:dict:update") + public Result update(@RequestBody SysDictDataDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysDictDataService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:dict:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysDictDataService.delete(ids); + + return new Result(); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictTypeController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictTypeController.java new file mode 100644 index 0000000..86278b5 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysDictTypeController.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.sys.dto.SysDictTypeDTO; +import io.renren.modules.sys.entity.DictType; +import io.renren.modules.sys.service.SysDictTypeService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.List; +import java.util.Map; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("sys/dict/type") +@Api(tags="字典类型") +public class SysDictTypeController { + @Autowired + private SysDictTypeService sysDictTypeService; + + @GetMapping("page") + @ApiOperation("字典类型") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "dictType", value = "字典类型", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "dictName", value = "字典名称", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:dict:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + //字典类型 + PageData page = sysDictTypeService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:dict:info") + public Result get(@PathVariable("id") Long id){ + SysDictTypeDTO data = sysDictTypeService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:dict:save") + public Result save(@RequestBody SysDictTypeDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + sysDictTypeService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:dict:update") + public Result update(@RequestBody SysDictTypeDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysDictTypeService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:dict:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysDictTypeService.delete(ids); + + return new Result(); + } + + @GetMapping("all") + @ApiOperation("所有字典数据") + public Result> all(){ + List list = sysDictTypeService.getAllList(); + + return new Result>().ok(list); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysMenuController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysMenuController.java new file mode 100644 index 0000000..6b6d523 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysMenuController.java @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.exception.ErrorCode; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.modules.security.service.ShiroService; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dto.SysMenuDTO; +import io.renren.modules.sys.enums.MenuTypeEnum; +import io.renren.modules.sys.service.SysMenuService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Set; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/menu") +@Api(tags="菜单管理") +public class SysMenuController { + @Autowired + private SysMenuService sysMenuService; + @Autowired + private ShiroService shiroService; + + @GetMapping("nav") + @ApiOperation("导航") + public Result> nav(){ + UserDetail user = SecurityUser.getUser(); + List list = sysMenuService.getUserMenuList(user, MenuTypeEnum.MENU.value()); + + return new Result>().ok(list); + } + + @GetMapping("permissions") + @ApiOperation("权限标识") + public Result> permissions(){ + UserDetail user = SecurityUser.getUser(); + Set set = shiroService.getUserPermissions(user); + + return new Result>().ok(set); + } + + @GetMapping("list") + @ApiOperation("列表") + @ApiImplicitParam(name = "type", value = "菜单类型 0:菜单 1:按钮 null:全部", paramType = "query", dataType="int") + @RequiresPermissions("sys:menu:list") + public Result> list(Integer type){ + List list = sysMenuService.getAllMenuList(type); + + return new Result>().ok(list); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:menu:info") + public Result get(@PathVariable("id") Long id){ + SysMenuDTO data = sysMenuService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:menu:save") + public Result save(@RequestBody SysMenuDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + sysMenuService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:menu:update") + public Result update(@RequestBody SysMenuDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, DefaultGroup.class); + + sysMenuService.update(dto); + + return new Result(); + } + + @DeleteMapping("{id}") + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:menu:delete") + public Result delete(@PathVariable("id") Long id){ + //效验数据 + AssertUtils.isNull(id, "id"); + + //判断是否有子菜单或按钮 + List list = sysMenuService.getListPid(id); + if(list.size() > 0){ + return new Result().error(ErrorCode.SUB_MENU_EXIST); + } + + sysMenuService.delete(id); + + return new Result(); + } + + @GetMapping("select") + @ApiOperation("角色菜单权限") + @RequiresPermissions("sys:menu:select") + public Result> select(){ + UserDetail user = SecurityUser.getUser(); + List list = sysMenuService.getUserMenuList(user, null); + + return new Result>().ok(list); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysParamsController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysParamsController.java new file mode 100644 index 0000000..de4f9b8 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysParamsController.java @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.sys.dto.SysParamsDTO; +import io.renren.modules.sys.excel.SysParamsExcel; +import io.renren.modules.sys.service.SysParamsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestController +@RequestMapping("sys/params") +@Api(tags="参数管理") +public class SysParamsController { + @Autowired + private SysParamsService sysParamsService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "paramCode", value = "参数编码", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:params:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysParamsService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:params:info") + public Result get(@PathVariable("id") Long id){ + SysParamsDTO data = sysParamsService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:params:save") + public Result save(@RequestBody SysParamsDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysParamsService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:params:update") + public Result update(@RequestBody SysParamsDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysParamsService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:params:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysParamsService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:params:export") + @ApiImplicitParam(name = "paramCode", value = "参数编码", paramType = "query", dataType="String") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysParamsService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysParamsExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysRoleController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysRoleController.java new file mode 100644 index 0000000..ce7a76f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysRoleController.java @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.sys.dto.SysRoleDTO; +import io.renren.modules.sys.service.SysRoleDataScopeService; +import io.renren.modules.sys.service.SysRoleMenuService; +import io.renren.modules.sys.service.SysRoleService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/role") +@Api(tags="角色管理") +public class SysRoleController { + @Autowired + private SysRoleService sysRoleService; + @Autowired + private SysRoleMenuService sysRoleMenuService; + @Autowired + private SysRoleDataScopeService sysRoleDataScopeService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "name", value = "角色名", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:role:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysRoleService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("list") + @ApiOperation("列表") + @RequiresPermissions("sys:role:list") + public Result> list(){ + List data = sysRoleService.list(new HashMap<>(1)); + + return new Result>().ok(data); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:role:info") + public Result get(@PathVariable("id") Long id){ + SysRoleDTO data = sysRoleService.get(id); + + //查询角色对应的菜单 + List menuIdList = sysRoleMenuService.getMenuIdList(id); + data.setMenuIdList(menuIdList); + + //查询角色对应的数据权限 + List deptIdList = sysRoleDataScopeService.getDeptIdList(id); + data.setDeptIdList(deptIdList); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:role:save") + public Result save(@RequestBody SysRoleDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysRoleService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:role:update") + public Result update(@RequestBody SysRoleDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysRoleService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:role:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysRoleService.delete(ids); + + return new Result(); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/controller/SysUserController.java b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysUserController.java new file mode 100644 index 0000000..a389d6e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/controller/SysUserController.java @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.page.PageData; +import io.renren.common.utils.ConvertUtils; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.security.password.PasswordUtils; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dto.PasswordDTO; +import io.renren.modules.sys.dto.SysUserDTO; +import io.renren.modules.sys.excel.SysUserExcel; +import io.renren.modules.sys.service.SysRoleUserService; +import io.renren.modules.sys.service.SysUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 用户管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/user") +@Api(tags="用户管理") +public class SysUserController { + @Autowired + private SysUserService sysUserService; + @Autowired + private SysRoleUserService sysRoleUserService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") , + @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "gender", value = "性别", paramType = "query", dataType="String"), + @ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "query", dataType="String") + }) + @RequiresPermissions("sys:user:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = sysUserService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("sys:user:info") + public Result get(@PathVariable("id") Long id){ + SysUserDTO data = sysUserService.get(id); + + //用户角色列表 + List roleIdList = sysRoleUserService.getRoleIdList(id); + data.setRoleIdList(roleIdList); + + return new Result().ok(data); + } + + @GetMapping("info") + @ApiOperation("登录用户信息") + public Result info(){ + SysUserDTO data = ConvertUtils.sourceToTarget(SecurityUser.getUser(), SysUserDTO.class); + return new Result().ok(data); + } + + @PutMapping("password") + @ApiOperation("修改密码") + @LogOperation("修改密码") + public Result password(@RequestBody PasswordDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto); + + UserDetail user = SecurityUser.getUser(); + + //原密码不正确 + if(!PasswordUtils.matches(dto.getPassword(), user.getPassword())){ + return new Result().error(ErrorCode.PASSWORD_ERROR); + } + + sysUserService.updatePassword(user.getId(), dto.getNewPassword()); + + return new Result(); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("sys:user:save") + public Result save(@RequestBody SysUserDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + sysUserService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("sys:user:update") + public Result update(@RequestBody SysUserDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + sysUserService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("sys:user:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + sysUserService.deleteBatchIds(Arrays.asList(ids)); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("sys:user:export") + @ApiImplicitParam(name = "username", value = "用户名", paramType = "query", dataType="String") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = sysUserService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SysUserExcel.class); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDeptDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDeptDao.java new file mode 100644 index 0000000..d098933 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDeptDao.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysDeptEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysDeptDao extends BaseDao { + + List getList(Map params); + + SysDeptEntity getById(Long id); + + /** + * 获取所有部门的id、pid列表 + */ + List getIdAndPidList(); + + /** + * 根据部门ID,获取所有子部门ID列表 + * @param id 部门ID + */ + List getSubDeptIdList(String id); + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictDataDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictDataDao.java new file mode 100644 index 0000000..61ec809 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictDataDao.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.DictData; +import io.renren.modules.sys.entity.SysDictDataEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysDictDataDao extends BaseDao { + + /** + * 字典数据列表 + */ + List getDictDataList(); +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictTypeDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictTypeDao.java new file mode 100644 index 0000000..fa6e05d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysDictTypeDao.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.DictType; +import io.renren.modules.sys.entity.SysDictTypeEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysDictTypeDao extends BaseDao { + + /** + * 字典类型列表 + */ + List getDictTypeList(); + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java new file mode 100644 index 0000000..039c14d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysMenuEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysMenuDao extends BaseDao { + + SysMenuEntity getById(@Param("id") Long id); + + /** + * 查询所有菜单列表 + * + * @param menuType 菜单类型 + */ + List getMenuList(@Param("menuType") Integer menuType); + + /** + * 查询用户菜单列表 + * + * @param userId 用户ID + * @param menuType 菜单类型 + */ + List getUserMenuList(@Param("userId") Long userId, @Param("menuType") Integer menuType); + + /** + * 查询用户权限列表 + * @param userId 用户ID + */ + List getUserPermissionsList(Long userId); + + /** + * 查询所有权限列表 + */ + List getPermissionsList(); + + /** + * 根据父菜单,查询子菜单 + * @param pid 父菜单ID + */ + List getListPid(Long pid); + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysParamsDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysParamsDao.java new file mode 100644 index 0000000..1d4c0cb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysParamsDao.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysParamsEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysParamsDao extends BaseDao { + /** + * 根据参数编码,查询value + * @param paramCode 参数编码 + * @return 参数值 + */ + String getValueByCode(String paramCode); + + /** + * 获取参数编码列表 + * @param ids ids + * @return 返回参数编码列表 + */ + List getParamCodeList(Long[] ids); + + /** + * 根据参数编码,更新value + * @param paramCode 参数编码 + * @param paramValue 参数值 + */ + int updateValueByCode(@Param("paramCode") String paramCode, @Param("paramValue") String paramValue); +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java new file mode 100644 index 0000000..68c7664 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysRoleEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysRoleDao extends BaseDao { + + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDataScopeDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDataScopeDao.java new file mode 100644 index 0000000..8ad26c8 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleDataScopeDao.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysRoleDataScopeEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysRoleDataScopeDao extends BaseDao { + + /** + * 根据角色ID,获取部门ID列表 + */ + List getDeptIdList(Long roleId); + + /** + * 获取用户的部门数据权限列表 + */ + List getDataScopeList(Long userId); + + /** + * 根据角色id,删除角色数据权限关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java new file mode 100644 index 0000000..ed9252b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysRoleMenuEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysRoleMenuDao extends BaseDao { + + /** + * 根据角色ID,获取菜单ID列表 + */ + List getMenuIdList(Long roleId); + + /** + * 根据角色id,删除角色菜单关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据菜单id,删除角色菜单关系 + * @param menuId 菜单id + */ + void deleteByMenuId(Long menuId); +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleUserDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleUserDao.java new file mode 100644 index 0000000..0038b12 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysRoleUserDao.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysRoleUserEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Mapper +public interface SysRoleUserDao extends BaseDao { + + /** + * 根据角色ids,删除角色用户关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据用户id,删除角色用户关系 + * @param userIds 用户ids + */ + void deleteByUserIds(Long[] userIds); + + /** + * 角色ID列表 + * @param userId 用户ID + * + * @return + */ + List getRoleIdList(Long userId); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dao/SysUserDao.java b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysUserDao.java new file mode 100644 index 0000000..fc3c46b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dao/SysUserDao.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.sys.entity.SysUserEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserDao extends BaseDao { + + List getList(Map params); + + SysUserEntity getById(Long id); + + SysUserEntity getByUsername(String username); + + int updatePassword(@Param("id") Long id, @Param("newPassword") String newPassword); + + /** + * 根据部门ID,查询用户数 + */ + int getCountByDeptId(Long deptId); + + /** + * 根据部门ID,查询用户ID列表 + */ + List getUserIdListByDeptId(List deptIdList); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/PasswordDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/PasswordDTO.java new file mode 100644 index 0000000..bc3f79d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/PasswordDTO.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 修改密码 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "修改密码") +public class PasswordDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "原密码") + @NotBlank(message="{sysuser.password.require}") + private String password; + + @ApiModelProperty(value = "新密码") + @NotBlank(message="{sysuser.password.require}") + private String newPassword; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDeptDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDeptDTO.java new file mode 100644 index 0000000..e9f3166 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDeptDTO.java @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.utils.TreeNode; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ApiModel(value = "部门管理") +public class SysDeptDTO extends TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "上级ID") + @NotNull(message="{sysdept.pid.require}", groups = DefaultGroup.class) + private Long pid; + + @ApiModelProperty(value = "部门名称") + @NotBlank(message="{sysdept.name.require}", groups = DefaultGroup.class) + private String name; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "上级部门名称") + private String parentName; + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public Long getPid() { + return pid; + } + + @Override + public void setPid(Long pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getSort() { + return sort; + } + + public void setSort(Integer sort) { + this.sort = sort; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictDataDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictDataDTO.java new file mode 100644 index 0000000..46b6ab6 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictDataDTO.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "字典数据") +public class SysDictDataDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "字典类型ID") + @NotNull(message="{sysdict.type.require}", groups = DefaultGroup.class) + private Long dictTypeId; + + @ApiModelProperty(value = "字典标签") + @NotBlank(message="{sysdict.label.require}", groups = DefaultGroup.class) + private String dictLabel; + + @ApiModelProperty(value = "字典值") + private String dictValue; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "更新时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictTypeDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictTypeDTO.java new file mode 100644 index 0000000..81ae398 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysDictTypeDTO.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "字典类型") +public class SysDictTypeDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "字典类型") + @NotBlank(message="{sysdict.type.require}", groups = DefaultGroup.class) + private String dictType; + + @ApiModelProperty(value = "字典名称") + @NotBlank(message="{sysdict.name.require}", groups = DefaultGroup.class) + private String dictName; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "更新时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SysMenuDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysMenuDTO.java new file mode 100644 index 0000000..e6a7b5e --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysMenuDTO.java @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.utils.TreeNode; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ApiModel(value = "菜单管理") +public class SysMenuDTO extends TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "上级ID") + @NotNull(message="{sysmenu.pid.require}", groups = DefaultGroup.class) + private Long pid; + + @ApiModelProperty(value = "菜单名称") + @NotBlank(message="{sysmenu.name.require}", groups = DefaultGroup.class) + private String name; + + @ApiModelProperty(value = "菜单URL") + private String url; + + @ApiModelProperty(value = "类型 0:菜单 1:按钮") + @Range(min=0, max=1, message = "{sysmenu.type.range}", groups = DefaultGroup.class) + private Integer menuType; + + @ApiModelProperty(value = "菜单图标") + private String icon; + + @ApiModelProperty(value = "授权(多个用逗号分隔,如:sys:user:list,sys:user:save)") + private String permissions; + + @ApiModelProperty(value = "排序") + @Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class) + private Integer sort; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "上级菜单名称") + private String parentName; + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public Long getPid() { + return pid; + } + + @Override + public void setPid(Long pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Integer getMenuType() { + return menuType; + } + + public void setMenuType(Integer menuType) { + this.menuType = menuType; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getPermissions() { + return permissions; + } + + public void setPermissions(String permissions) { + this.permissions = permissions; + } + + public Integer getSort() { + return sort; + } + + public void setSort(Integer sort) { + this.sort = sort; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SysParamsDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysParamsDTO.java new file mode 100644 index 0000000..bf275a7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysParamsDTO.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "参数管理") +public class SysParamsDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "参数编码") + @NotBlank(message="{sysparams.paramcode.require}", groups = DefaultGroup.class) + private String paramCode; + + @ApiModelProperty(value = "参数值") + @NotBlank(message="{sysparams.paramvalue.require}", groups = DefaultGroup.class) + private String paramValue; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "更新时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date updateDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SysRoleDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysRoleDTO.java new file mode 100644 index 0000000..a57b4b3 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysRoleDTO.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "角色管理") +public class SysRoleDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "角色名称") + @NotBlank(message="{sysrole.name.require}", groups = DefaultGroup.class) + private String name; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "菜单ID列表") + private List menuIdList; + + @ApiModelProperty(value = "部门ID列表") + private List deptIdList; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SysUserDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysUserDTO.java new file mode 100644 index 0000000..c42a66f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SysUserDTO.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Range; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 用户管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "用户管理") +public class SysUserDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + @Null(message="{id.null}", groups = AddGroup.class) + @NotNull(message="{id.require}", groups = UpdateGroup.class) + private Long id; + + @ApiModelProperty(value = "用户名", required = true) + @NotBlank(message="{sysuser.username.require}", groups = DefaultGroup.class) + private String username; + + @ApiModelProperty(value = "密码") + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + @NotBlank(message="{sysuser.password.require}", groups = AddGroup.class) + private String password; + + @ApiModelProperty(value = "姓名", required = true) + @NotBlank(message="{sysuser.realname.require}", groups = DefaultGroup.class) + private String realName; + + @ApiModelProperty(value = "头像") + private String headUrl; + + @ApiModelProperty(value = "性别 0:男 1:女 2:保密", required = true) + @Range(min=0, max=2, message = "{sysuser.gender.range}", groups = DefaultGroup.class) + private Integer gender; + + @ApiModelProperty(value = "邮箱") + @Email(message="{sysuser.email.error}", groups = DefaultGroup.class) + private String email; + + @ApiModelProperty(value = "手机号") + private String mobile; + + @ApiModelProperty(value = "部门ID", required = true) + @NotNull(message="{sysuser.deptId.require}", groups = DefaultGroup.class) + private Long deptId; + + @ApiModelProperty(value = "状态 0:停用 1:正常", required = true) + @Range(min=0, max=1, message = "{sysuser.status.range}", groups = DefaultGroup.class) + private Integer status; + + @ApiModelProperty(value = "创建时间") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Date createDate; + + @ApiModelProperty(value = "超级管理员 0:否 1:是") + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + private Integer superAdmin; + + @ApiModelProperty(value = "角色ID列表") + private List roleIdList; + + @ApiModelProperty(value = "部门名称") + private String deptName; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/dto/SystemDTO.java b/renren-admin/src/main/java/io/renren/modules/sys/dto/SystemDTO.java new file mode 100644 index 0000000..1412b41 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/dto/SystemDTO.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dto; + +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 系统数据 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@ApiModel(value = "系统数据") +public class SystemDTO implements Serializable { + private static final long serialVersionUID = 1L; + + private Long sysTime; + private String osName; + private String osArch; + private String osVersion; + private String userLanguage; + private String userDir; + private Long totalPhysical; + private Long freePhysical; + private BigDecimal memoryRate; + private Integer processors; + private String jvmName; + private String javaVersion; + private String javaHome; + private Long javaTotalMemory; + private Long javaFreeMemory; + private Long javaMaxMemory; + private String userName; + private BigDecimal systemCpuLoad; + private String userTimezone; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/DictData.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/DictData.java new file mode 100644 index 0000000..4b5d451 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/DictData.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2019 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +/** + * 字典数据 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public class DictData { + @JsonIgnore + private Long dictTypeId; + private String dictLabel; + private String dictValue; +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/DictType.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/DictType.java new file mode 100644 index 0000000..a391710 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/DictType.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2019 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public class DictType { + @JsonIgnore + private Long id; + private String dictType; + private List dataList = new ArrayList<>(); +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDeptEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDeptEntity.java new file mode 100644 index 0000000..9f85551 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDeptEntity.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_dept") +public class SysDeptEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 上级ID + */ + private Long pid; + /** + * 所有上级ID,用逗号分开 + */ + private String pids; + /** + * 部门名称 + */ + private String name; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 上级部门名称 + */ + @TableField(exist = false) + private String parentName; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictDataEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictDataEntity.java new file mode 100644 index 0000000..b84197b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictDataEntity.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 数据字典 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_dict_data") +public class SysDictDataEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 字典类型ID + */ + private Long dictTypeId; + /** + * 字典标签 + */ + private String dictLabel; + /** + * 字典值 + */ + private String dictValue; + /** + * 备注 + */ + private String remark; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictTypeEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictTypeEntity.java new file mode 100644 index 0000000..2a830ef --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysDictTypeEntity.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_dict_type") +public class SysDictTypeEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 字典类型 + */ + private String dictType; + /** + * 字典名称 + */ + private String dictName; + /** + * 备注 + */ + private String remark; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java new file mode 100644 index 0000000..3168339 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_menu") +public class SysMenuEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 父菜单ID,一级菜单为0 + */ + private Long pid; + /** + * 菜单名称 + */ + private String name; + /** + * 菜单URL + */ + private String url; + /** + * 授权(多个用逗号分隔,如:sys:user:list,sys:user:save) + */ + private String permissions; + /** + * 类型 0:菜单 1:按钮 + */ + private Integer menuType; + /** + * 菜单图标 + */ + private String icon; + /** + * 排序 + */ + private Integer sort; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 上级菜单名称 + */ + @TableField(exist = false) + private String parentName; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysParamsEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysParamsEntity.java new file mode 100644 index 0000000..fb7e62d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysParamsEntity.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_params") +public class SysParamsEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 参数编码 + */ + private String paramCode; + /** + * 参数值 + */ + private String paramValue; + /** + * 类型 0:系统参数 1:非系统参数 + */ + private Integer paramType; + /** + * 备注 + */ + private String remark; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleDataScopeEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleDataScopeEntity.java new file mode 100644 index 0000000..38188f8 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleDataScopeEntity.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role_data_scope") +public class SysRoleDataScopeEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 角色ID + */ + private Long roleId; + /** + * 部门ID + */ + private Long deptId; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java new file mode 100644 index 0000000..ed02e52 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role") +public class SysRoleEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 角色名称 + */ + private String name; + /** + * 备注 + */ + private String remark; + /** + * 部门ID + */ + @TableField(fill = FieldFill.INSERT) + private Long deptId; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java new file mode 100644 index 0000000..a654e6d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色菜单关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role_menu") +public class SysRoleMenuEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 角色ID + */ + private Long roleId; + /** + * 菜单ID + */ + private Long menuId; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleUserEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleUserEntity.java new file mode 100644 index 0000000..d793da5 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysRoleUserEntity.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_role_user") +public class SysRoleUserEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + + /** + * 角色ID + */ + private Long roleId; + /** + * 用户ID + */ + private Long userId; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java new file mode 100644 index 0000000..864c7eb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.entity.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("sys_user") +public class SysUserEntity extends BaseEntity { + private static final long serialVersionUID = 1L; + /** + * 用户名 + */ + private String username; + /** + * 密码 + */ + private String password; + /** + * 姓名 + */ + private String realName; + /** + * 头像 + */ + private String headUrl; + /** + * 性别 0:男 1:女 2:保密 + */ + private Integer gender; + /** + * 邮箱 + */ + private String email; + /** + * 手机号 + */ + private String mobile; + /** + * 部门ID + */ + private Long deptId; + /** + * 超级管理员 0:否 1:是 + */ + private Integer superAdmin; + /** + * 状态 0:停用 1:正常 + */ + private Integer status; + /** + * 更新者 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updater; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateDate; + /** + * 部门名称 + */ + @TableField(exist=false) + private String deptName; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/enums/MenuTypeEnum.java b/renren-admin/src/main/java/io/renren/modules/sys/enums/MenuTypeEnum.java new file mode 100644 index 0000000..3cf2ba9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/enums/MenuTypeEnum.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.enums; + +/** + * 菜单类型枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum MenuTypeEnum { + /** + * 菜单 + */ + MENU(0), + /** + * 按钮 + */ + BUTTON(1); + + private int value; + + MenuTypeEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/enums/SuperAdminEnum.java b/renren-admin/src/main/java/io/renren/modules/sys/enums/SuperAdminEnum.java new file mode 100644 index 0000000..1c32493 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/enums/SuperAdminEnum.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.enums; + +/** + * 超级管理员枚举 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum SuperAdminEnum { + YES(1), + NO(0); + + private int value; + + SuperAdminEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/enums/UserStatusEnum.java b/renren-admin/src/main/java/io/renren/modules/sys/enums/UserStatusEnum.java new file mode 100644 index 0000000..ae114b4 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/enums/UserStatusEnum.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.enums; + +/** + * 用户状态 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public enum UserStatusEnum { + DISABLE(0), + ENABLED(1); + + private int value; + + UserStatusEnum(int value) { + this.value = value; + } + + public int value() { + return this.value; + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/excel/SysParamsExcel.java b/renren-admin/src/main/java/io/renren/modules/sys/excel/SysParamsExcel.java new file mode 100644 index 0000000..f913e89 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/excel/SysParamsExcel.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysParamsExcel { + @Excel(name = "参数编码") + private String paramCode; + @Excel(name = "参数值") + private String paramValue; + @Excel(name = "备注") + private String remark; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/excel/SysUserExcel.java b/renren-admin/src/main/java/io/renren/modules/sys/excel/SysUserExcel.java new file mode 100644 index 0000000..287bde2 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/excel/SysUserExcel.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 用户管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Data +public class SysUserExcel { + @Excel(name = "用户名") + private String username; + @Excel(name = "姓名") + private String realName; + @Excel(name = "性别", replace = {"男_0", "女_1", "保密_2"}) + private Integer gender; + @Excel(name = "邮箱") + private String email; + @Excel(name = "手机号") + private String mobile; + @Excel(name = "部门名称") + private String deptName; + @Excel(name = "状态", replace = {"停用_0", "正常_1"}) + private Integer status; + @Excel(name = "备注") + private String remark; + @Excel(name = "创建时间", format = "yyyy-MM-dd HH:mm:ss") + private Date createDate; + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/redis/SysParamsRedis.java b/renren-admin/src/main/java/io/renren/modules/sys/redis/SysParamsRedis.java new file mode 100644 index 0000000..99af7b5 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/redis/SysParamsRedis.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.redis; + +import io.renren.common.redis.RedisKeys; +import io.renren.common.redis.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Component +public class SysParamsRedis { + @Autowired + private RedisUtils redisUtils; + + public void delete(Object[] paramCodes) { + String key = RedisKeys.getSysParamsKey(); + redisUtils.hDel(key, paramCodes); + } + + public void set(String paramCode, String paramValue){ + if(paramValue == null){ + return ; + } + String key = RedisKeys.getSysParamsKey(); + redisUtils.hSet(key, paramCode, paramValue); + } + + public String get(String paramCode){ + String key = RedisKeys.getSysParamsKey(); + return (String)redisUtils.hGet(key, paramCode); + } + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysDeptService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysDeptService.java new file mode 100644 index 0000000..5f1047f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysDeptService.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.service.BaseService; +import io.renren.modules.sys.dto.SysDeptDTO; +import io.renren.modules.sys.entity.SysDeptEntity; + +import java.util.List; +import java.util.Map; + +/** + * 部门管理 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysDeptService extends BaseService { + + List list(Map params); + + SysDeptDTO get(Long id); + + void save(SysDeptDTO dto); + + void update(SysDeptDTO dto); + + void delete(Long id); + + /** + * 根据部门ID,获取本部门及子部门ID列表 + * @param id 部门ID + */ + List getSubDeptIdList(Long id); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysDictDataService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysDictDataService.java new file mode 100644 index 0000000..8f67ccb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysDictDataService.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.sys.dto.SysDictDataDTO; +import io.renren.modules.sys.entity.SysDictDataEntity; + +import java.util.Map; + +/** + * 数据字典 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysDictDataService extends BaseService { + + PageData page(Map params); + + SysDictDataDTO get(Long id); + + void save(SysDictDataDTO dto); + + void update(SysDictDataDTO dto); + + void delete(Long[] ids); + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysDictTypeService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysDictTypeService.java new file mode 100644 index 0000000..6c051ae --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysDictTypeService.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.sys.dto.SysDictTypeDTO; +import io.renren.modules.sys.entity.DictType; +import io.renren.modules.sys.entity.SysDictTypeEntity; + +import java.util.List; +import java.util.Map; + +/** + * 数据字典 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysDictTypeService extends BaseService { + + PageData page(Map params); + + SysDictTypeDTO get(Long id); + + void save(SysDictTypeDTO dto); + + void update(SysDictTypeDTO dto); + + void delete(Long[] ids); + + /** + * 获取所有字典 + */ + List getAllList(); + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysMenuService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysMenuService.java new file mode 100644 index 0000000..8243978 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysMenuService.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.service.BaseService; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dto.SysMenuDTO; +import io.renren.modules.sys.entity.SysMenuEntity; + +import java.util.List; + + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysMenuService extends BaseService { + + SysMenuDTO get(Long id); + + void save(SysMenuDTO dto); + + void update(SysMenuDTO dto); + + void delete(Long id); + + /** + * 菜单列表 + * + * @param menuType 菜单类型 + */ + List getAllMenuList(Integer menuType); + + /** + * 用户菜单列表 + * + * @param user 用户 + * @param menuType 菜单类型 + */ + List getUserMenuList(UserDetail user, Integer menuType); + + /** + * 根据父菜单,查询子菜单 + * @param pid 父菜单ID + */ + List getListPid(Long pid); +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysParamsService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysParamsService.java new file mode 100644 index 0000000..0629aec --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysParamsService.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.sys.dto.SysParamsDTO; +import io.renren.modules.sys.entity.SysParamsEntity; + +import java.util.List; +import java.util.Map; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysParamsService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + SysParamsDTO get(Long id); + + void save(SysParamsDTO dto); + + void update(SysParamsDTO dto); + + void delete(Long[] ids); + + /** + * 根据参数编码,获取参数的value值 + * + * @param paramCode 参数编码 + */ + String getValue(String paramCode); + + /** + * 根据参数编码,获取value的Object对象 + * @param paramCode 参数编码 + * @param clazz Object对象 + */ + T getValueObject(String paramCode, Class clazz); + + /** + * 根据参数编码,更新value + * @param paramCode 参数编码 + * @param paramValue 参数值 + */ + int updateValueByCode(String paramCode, String paramValue); +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleDataScopeService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleDataScopeService.java new file mode 100644 index 0000000..59f8668 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleDataScopeService.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.service.BaseService; +import io.renren.modules.sys.entity.SysRoleDataScopeEntity; + +import java.util.List; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysRoleDataScopeService extends BaseService { + + /** + * 根据角色ID,获取部门ID列表 + */ + List getDeptIdList(Long roleId); + + /** + * 保存或修改 + * @param roleId 角色ID + * @param deptIdList 部门ID列表 + */ + void saveOrUpdate(Long roleId, List deptIdList); + + /** + * 根据角色id,删除角色数据权限关系 + * @param roleId 角色ids + */ + void deleteByRoleIds(Long[] roleId); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java new file mode 100644 index 0000000..e7d54a1 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.service.BaseService; +import io.renren.modules.sys.entity.SysRoleMenuEntity; + +import java.util.List; + + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysRoleMenuService extends BaseService { + + /** + * 根据角色ID,获取菜单ID列表 + */ + List getMenuIdList(Long roleId); + + /** + * 保存或修改 + * @param roleId 角色ID + * @param menuIdList 菜单ID列表 + */ + void saveOrUpdate(Long roleId, List menuIdList); + + /** + * 根据角色id,删除角色菜单关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据菜单id,删除角色菜单关系 + * @param menuId 菜单id + */ + void deleteByMenuId(Long menuId); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleService.java new file mode 100644 index 0000000..b0fd212 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleService.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.sys.dto.SysRoleDTO; +import io.renren.modules.sys.entity.SysRoleEntity; + +import java.util.List; +import java.util.Map; + + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysRoleService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + SysRoleDTO get(Long id); + + void save(SysRoleDTO dto); + + void update(SysRoleDTO dto); + + void delete(Long[] ids); + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleUserService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleUserService.java new file mode 100644 index 0000000..de33bda --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysRoleUserService.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.service.BaseService; +import io.renren.modules.sys.entity.SysRoleUserEntity; + +import java.util.List; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface SysRoleUserService extends BaseService { + + /** + * 保存或修改 + * @param userId 用户ID + * @param roleIdList 角色ID列表 + */ + void saveOrUpdate(Long userId, List roleIdList); + + /** + * 根据角色ids,删除角色用户关系 + * @param roleIds 角色ids + */ + void deleteByRoleIds(Long[] roleIds); + + /** + * 根据用户id,删除角色用户关系 + * @param userIds 用户ids + */ + void deleteByUserIds(Long[] userIds); + + /** + * 角色ID列表 + * @param userId 用户ID + */ + List getRoleIdList(Long userId); +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/SysUserService.java b/renren-admin/src/main/java/io/renren/modules/sys/service/SysUserService.java new file mode 100644 index 0000000..78f68f3 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/SysUserService.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.modules.sys.dto.SysUserDTO; +import io.renren.modules.sys.entity.SysUserEntity; + +import java.util.List; +import java.util.Map; + + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysUserService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + SysUserDTO get(Long id); + + SysUserDTO getByUsername(String username); + + void save(SysUserDTO dto); + + void update(SysUserDTO dto); + + void delete(Long[] ids); + + /** + * 修改密码 + * @param id 用户ID + * @param newPassword 新密码 + */ + void updatePassword(Long id, String newPassword); + + /** + * 根据部门ID,查询用户数 + */ + int getCountByDeptId(Long deptId); + + /** + * 根据部门ID,查询用户Id列表 + */ + List getUserIdListByDeptId(List deptIdList); + +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDeptServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDeptServiceImpl.java new file mode 100644 index 0000000..0a0c7e9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDeptServiceImpl.java @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.common.utils.TreeUtils; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dao.SysDeptDao; +import io.renren.modules.sys.dao.SysUserDao; +import io.renren.modules.sys.dto.SysDeptDTO; +import io.renren.modules.sys.entity.SysDeptEntity; +import io.renren.modules.sys.enums.SuperAdminEnum; +import io.renren.modules.sys.service.SysDeptService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +@Service +public class SysDeptServiceImpl extends BaseServiceImpl implements SysDeptService { + @Autowired + private SysUserDao sysUserDao; + + @Override + public List list(Map params) { + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + params.put("deptIdList", getSubDeptIdList(user.getDeptId())); + } + + //查询部门列表 + List entityList = baseDao.getList(params); + + List dtoList = ConvertUtils.sourceToTarget(entityList, SysDeptDTO.class); + + return TreeUtils.build(dtoList); + } + + @Override + public SysDeptDTO get(Long id) { + //超级管理员,部门ID为null + if(id == null){ + return null; + } + + SysDeptEntity entity = baseDao.getById(id); + + return ConvertUtils.sourceToTarget(entity, SysDeptDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysDeptDTO dto) { + SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, SysDeptEntity.class); + + entity.setPids(getPidList(entity.getPid())); + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysDeptDTO dto) { + SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, SysDeptEntity.class); + + //上级部门不能为自身 + if(entity.getId().equals(entity.getPid())){ + throw new RenException(ErrorCode.SUPERIOR_DEPT_ERROR); + } + + //上级部门不能为下级部门 + List subDeptList = getSubDeptIdList(entity.getId()); + if(subDeptList.contains(entity.getPid())){ + throw new RenException(ErrorCode.SUPERIOR_DEPT_ERROR); + } + + entity.setPids(getPidList(entity.getPid())); + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + //判断是否有子部门 + List subList = getSubDeptIdList(id); + if(subList.size() > 1){ + throw new RenException(ErrorCode.DEPT_SUB_DELETE_ERROR); + } + + //判断部门下面是否有用户 + int count = sysUserDao.getCountByDeptId(id); + if(count > 0){ + throw new RenException(ErrorCode.DEPT_USER_DELETE_ERROR); + } + + //删除 + baseDao.deleteById(id); + } + + @Override + public List getSubDeptIdList(Long id) { + List deptIdList = baseDao.getSubDeptIdList("%" + id + "%"); + deptIdList.add(id); + + return deptIdList; + } + + /** + * 获取所有上级部门ID + * @param pid 上级ID + */ + private String getPidList(Long pid){ + //顶级部门,无上级部门 + if(Constant.DEPT_ROOT.equals(pid)){ + return Constant.DEPT_ROOT + ""; + } + + //所有部门的id、pid列表 + List deptList = baseDao.getIdAndPidList(); + + //list转map + Map map = new HashMap<>(deptList.size()); + for(SysDeptEntity entity : deptList){ + map.put(entity.getId(), entity); + } + + //递归查询所有上级部门ID列表 + List pidList = new ArrayList<>(); + getPidTree(pid, map, pidList); + + return StringUtils.join(pidList, ","); + } + + private void getPidTree(Long pid, Map map, List pidList) { + //顶级部门,无上级部门 + if(Constant.DEPT_ROOT.equals(pid)){ + return ; + } + + //上级部门存在 + SysDeptEntity parent = map.get(pid); + if(parent != null){ + getPidTree(parent.getPid(), map, pidList); + } + + pidList.add(pid); + } +} diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictDataServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictDataServiceImpl.java new file mode 100644 index 0000000..739da51 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictDataServiceImpl.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.sys.dao.SysDictDataDao; +import io.renren.modules.sys.dto.SysDictDataDTO; +import io.renren.modules.sys.entity.SysDictDataEntity; +import io.renren.modules.sys.service.SysDictDataService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.Map; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysDictDataServiceImpl extends BaseServiceImpl implements SysDictDataService { + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, "sort", true), + getWrapper(params) + ); + + return getPageData(page, SysDictDataDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String dictTypeId = (String) params.get("dictTypeId"); + String dictLabel = (String) params.get("dictLabel"); + String dictValue = (String) params.get("dictValue"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("dict_type_id", dictTypeId); + wrapper.like(StringUtils.isNotBlank(dictLabel), "dict_label", dictLabel); + wrapper.like(StringUtils.isNotBlank(dictValue), "dict_value", dictValue); + + return wrapper; + } + + @Override + public SysDictDataDTO get(Long id) { + SysDictDataEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysDictDataDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysDictDataDTO dto) { + SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class); + + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysDictDataDTO dto) { + SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class); + + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除 + deleteBatchIds(Arrays.asList(ids)); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictTypeServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictTypeServiceImpl.java new file mode 100644 index 0000000..35c348b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysDictTypeServiceImpl.java @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.sys.dao.SysDictDataDao; +import io.renren.modules.sys.dao.SysDictTypeDao; +import io.renren.modules.sys.dto.SysDictTypeDTO; +import io.renren.modules.sys.entity.DictData; +import io.renren.modules.sys.entity.DictType; +import io.renren.modules.sys.entity.SysDictTypeEntity; +import io.renren.modules.sys.service.SysDictTypeService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 字典类型 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysDictTypeServiceImpl extends BaseServiceImpl implements SysDictTypeService { + @Autowired + private SysDictDataDao sysDictDataDao; + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, "sort", true), + getWrapper(params) + ); + + return getPageData(page, SysDictTypeDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String dictType = (String) params.get("dictType"); + String dictName = (String) params.get("dictName"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.like(StringUtils.isNotBlank(dictType), "dict_type", dictType); + wrapper.like(StringUtils.isNotBlank(dictName), "dict_name", dictName); + + return wrapper; + } + + @Override + public SysDictTypeDTO get(Long id) { + SysDictTypeEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysDictTypeDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysDictTypeDTO dto) { + SysDictTypeEntity entity = ConvertUtils.sourceToTarget(dto, SysDictTypeEntity.class); + + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysDictTypeDTO dto) { + SysDictTypeEntity entity = ConvertUtils.sourceToTarget(dto, SysDictTypeEntity.class); + + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除 + deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public List getAllList() { + List typeList = baseDao.getDictTypeList(); + List dataList = sysDictDataDao.getDictDataList(); + for(DictType type : typeList){ + for(DictData data : dataList){ + if(type.getId().equals(data.getDictTypeId())){ + type.getDataList().add(data); + } + } + } + return typeList; + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..dd48197 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.common.utils.TreeUtils; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dao.SysMenuDao; +import io.renren.modules.sys.dto.SysMenuDTO; +import io.renren.modules.sys.entity.SysMenuEntity; +import io.renren.modules.sys.enums.SuperAdminEnum; +import io.renren.modules.sys.service.SysMenuService; +import io.renren.modules.sys.service.SysRoleMenuService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +public class SysMenuServiceImpl extends BaseServiceImpl implements SysMenuService { + @Autowired + private SysRoleMenuService sysRoleMenuService; + + @Override + public SysMenuDTO get(Long id) { + SysMenuEntity entity = baseDao.getById(id); + + SysMenuDTO dto = ConvertUtils.sourceToTarget(entity, SysMenuDTO.class); + + return dto; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysMenuDTO dto) { + SysMenuEntity entity = ConvertUtils.sourceToTarget(dto, SysMenuEntity.class); + + //保存菜单 + insert(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysMenuDTO dto) { + SysMenuEntity entity = ConvertUtils.sourceToTarget(dto, SysMenuEntity.class); + + //上级菜单不能为自身 + if(entity.getId().equals(entity.getPid())){ + throw new RenException(ErrorCode.SUPERIOR_MENU_ERROR); + } + + //更新菜单 + updateById(entity); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long id) { + //删除菜单 + deleteById(id); + + //删除角色菜单关系 + sysRoleMenuService.deleteByMenuId(id); + } + + @Override + public List getAllMenuList(Integer menuType) { + List menuList = baseDao.getMenuList(menuType); + + List dtoList = ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class); + + return TreeUtils.build(dtoList, Constant.MENU_ROOT); + } + + @Override + public List getUserMenuList(UserDetail user, Integer menuType) { + List menuList; + + //系统管理员,拥有最高权限 + if(user.getSuperAdmin() == SuperAdminEnum.YES.value()){ + menuList = baseDao.getMenuList(menuType); + }else { + menuList = baseDao.getUserMenuList(user.getId(), menuType); + } + + List dtoList = ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class); + + return TreeUtils.build(dtoList); + } + + @Override + public List getListPid(Long pid) { + List menuList = baseDao.getListPid(pid); + + return ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysParamsServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysParamsServiceImpl.java new file mode 100644 index 0000000..3a15a2c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysParamsServiceImpl.java @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.common.utils.JsonUtils; +import io.renren.modules.sys.dao.SysParamsDao; +import io.renren.modules.sys.dto.SysParamsDTO; +import io.renren.modules.sys.entity.SysParamsEntity; +import io.renren.modules.sys.redis.SysParamsRedis; +import io.renren.modules.sys.service.SysParamsService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 参数管理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysParamsServiceImpl extends BaseServiceImpl implements SysParamsService { + @Autowired + private SysParamsRedis sysParamsRedis; + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysParamsDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysParamsDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String paramCode = (String) params.get("paramCode"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("param_type", 1); + wrapper.like(StringUtils.isNotBlank(paramCode), "param_code", paramCode); + + return wrapper; + } + + @Override + public SysParamsDTO get(Long id) { + SysParamsEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysParamsDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysParamsDTO dto) { + SysParamsEntity entity = ConvertUtils.sourceToTarget(dto, SysParamsEntity.class); + insert(entity); + + sysParamsRedis.set(entity.getParamCode(), entity.getParamValue()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysParamsDTO dto) { + SysParamsEntity entity = ConvertUtils.sourceToTarget(dto, SysParamsEntity.class); + updateById(entity); + + sysParamsRedis.set(entity.getParamCode(), entity.getParamValue()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除Redis数据 + List paramCodeList = baseDao.getParamCodeList(ids); + String[] paramCodes = paramCodeList.toArray(new String[paramCodeList.size()]); + sysParamsRedis.delete(paramCodes); + + //删除 + deleteBatchIds(Arrays.asList(ids)); + } + + @Override + public String getValue(String paramCode) { + String paramValue = sysParamsRedis.get(paramCode); + if(paramValue == null){ + paramValue = baseDao.getValueByCode(paramCode); + + sysParamsRedis.set(paramCode, paramValue); + } + return paramValue; + } + + @Override + public T getValueObject(String paramCode, Class clazz) { + String paramValue = getValue(paramCode); + if(StringUtils.isNotBlank(paramValue)){ + return JsonUtils.parseObject(paramValue, clazz); + } + + try { + return clazz.newInstance(); + } catch (Exception e) { + throw new RenException(ErrorCode.PARAMS_GET_ERROR); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int updateValueByCode(String paramCode, String paramValue) { + int count = baseDao.updateValueByCode(paramCode, paramValue); + sysParamsRedis.set(paramCode, paramValue); + return count; + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java new file mode 100644 index 0000000..1dcd2d9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleDataScopeServiceImpl.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import cn.hutool.core.collection.CollUtil; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.modules.sys.dao.SysRoleDataScopeDao; +import io.renren.modules.sys.entity.SysRoleDataScopeEntity; +import io.renren.modules.sys.service.SysRoleDataScopeService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 角色数据权限 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysRoleDataScopeServiceImpl extends BaseServiceImpl + implements SysRoleDataScopeService { + + @Override + public List getDeptIdList(Long roleId) { + return baseDao.getDeptIdList(roleId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveOrUpdate(Long roleId, List deptIdList) { + //先删除角色数据权限关系 + deleteByRoleIds(new Long[]{roleId}); + + //角色没有一个数据权限的情况 + if(CollUtil.isEmpty(deptIdList)){ + return ; + } + + //保存角色数据权限关系 + for(Long deptId : deptIdList){ + SysRoleDataScopeEntity sysRoleDataScopeEntity = new SysRoleDataScopeEntity(); + sysRoleDataScopeEntity.setDeptId(deptId); + sysRoleDataScopeEntity.setRoleId(roleId); + + //保存 + insert(sysRoleDataScopeEntity); + } + } + + @Override + public void deleteByRoleIds(Long[] roleIds) { + baseDao.deleteByRoleIds(roleIds); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java new file mode 100644 index 0000000..6f66b4f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import cn.hutool.core.collection.CollUtil; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.modules.sys.dao.SysRoleMenuDao; +import io.renren.modules.sys.entity.SysRoleMenuEntity; +import io.renren.modules.sys.service.SysRoleMenuService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysRoleMenuServiceImpl extends BaseServiceImpl implements SysRoleMenuService { + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveOrUpdate(Long roleId, List menuIdList) { + //先删除角色菜单关系 + deleteByRoleIds(new Long[]{roleId}); + + //角色没有一个菜单权限的情况 + if(CollUtil.isEmpty(menuIdList)){ + return ; + } + + //保存角色菜单关系 + for(Long menuId : menuIdList){ + SysRoleMenuEntity sysRoleMenuEntity = new SysRoleMenuEntity(); + sysRoleMenuEntity.setMenuId(menuId); + sysRoleMenuEntity.setRoleId(roleId); + + //保存 + insert(sysRoleMenuEntity); + } + } + + @Override + public List getMenuIdList(Long roleId){ + return baseDao.getMenuIdList(roleId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteByRoleIds(Long[] roleIds) { + baseDao.deleteByRoleIds(roleIds); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteByMenuId(Long menuId) { + baseDao.deleteByMenuId(menuId); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..5ceb247 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dao.SysRoleDao; +import io.renren.modules.sys.dto.SysRoleDTO; +import io.renren.modules.sys.entity.SysRoleEntity; +import io.renren.modules.sys.enums.SuperAdminEnum; +import io.renren.modules.sys.service.*; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysRoleServiceImpl extends BaseServiceImpl implements SysRoleService { + @Autowired + private SysRoleMenuService sysRoleMenuService; + @Autowired + private SysRoleDataScopeService sysRoleDataScopeService; + @Autowired + private SysRoleUserService sysRoleUserService; + @Autowired + private SysDeptService sysDeptService; + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, Constant.CREATE_DATE, false), + getWrapper(params) + ); + + return getPageData(page, SysRoleDTO.class); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, SysRoleDTO.class); + } + + private QueryWrapper getWrapper(Map params){ + String name = (String)params.get("name"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.like(StringUtils.isNotBlank(name), "name", name); + + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + List deptIdList = sysDeptService.getSubDeptIdList(user.getDeptId()); + wrapper.in(deptIdList != null, "dept_id", deptIdList); + } + + return wrapper; + } + + @Override + public SysRoleDTO get(Long id) { + SysRoleEntity entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, SysRoleDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysRoleDTO dto) { + SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class); + + //保存角色 + insert(entity); + + //保存角色菜单关系 + sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList()); + + //保存角色数据权限关系 + sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysRoleDTO dto) { + SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class); + + //更新角色 + updateById(entity); + + //更新角色菜单关系 + sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList()); + + //更新角色数据权限关系 + sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(Long[] ids) { + //删除角色 + baseDao.deleteBatchIds(Arrays.asList(ids)); + + //删除角色用户关系 + sysRoleUserService.deleteByRoleIds(ids); + + //删除角色菜单关系 + sysRoleMenuService.deleteByRoleIds(ids); + + //删除角色数据权限关系 + sysRoleDataScopeService.deleteByRoleIds(ids); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleUserServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleUserServiceImpl.java new file mode 100644 index 0000000..691886d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysRoleUserServiceImpl.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import cn.hutool.core.collection.CollUtil; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.modules.sys.dao.SysRoleUserDao; +import io.renren.modules.sys.entity.SysRoleUserEntity; +import io.renren.modules.sys.service.SysRoleUserService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 角色用户关系 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Service +public class SysRoleUserServiceImpl extends BaseServiceImpl implements SysRoleUserService { + + @Override + public void saveOrUpdate(Long userId, List roleIdList) { + //先删除角色用户关系 + deleteByUserIds(new Long[]{userId}); + + //用户没有一个角色权限的情况 + if(CollUtil.isEmpty(roleIdList)){ + return ; + } + + //保存角色用户关系 + for(Long roleId : roleIdList){ + SysRoleUserEntity sysRoleUserEntity = new SysRoleUserEntity(); + sysRoleUserEntity.setUserId(userId); + sysRoleUserEntity.setRoleId(roleId); + + //保存 + insert(sysRoleUserEntity); + } + } + + @Override + public void deleteByRoleIds(Long[] roleIds) { + baseDao.deleteByRoleIds(roleIds); + } + + @Override + public void deleteByUserIds(Long[] userIds) { + baseDao.deleteByUserIds(userIds); + } + + @Override + public List getRoleIdList(Long userId) { + + return baseDao.getRoleIdList(userId); + } +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..27a4780 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.utils.ConvertUtils; +import io.renren.modules.security.password.PasswordUtils; +import io.renren.modules.security.user.SecurityUser; +import io.renren.modules.security.user.UserDetail; +import io.renren.modules.sys.dao.SysUserDao; +import io.renren.modules.sys.dto.SysUserDTO; +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.enums.SuperAdminEnum; +import io.renren.modules.sys.service.SysDeptService; +import io.renren.modules.sys.service.SysRoleUserService; +import io.renren.modules.sys.service.SysUserService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysUserServiceImpl extends BaseServiceImpl implements SysUserService { + @Autowired + private SysRoleUserService sysRoleUserService; + @Autowired + private SysDeptService sysDeptService; + + @Override + public PageData page(Map params) { + //转换成like + paramsToLike(params, "username"); + + //分页 + IPage page = getPage(params, Constant.CREATE_DATE, false); + + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId())); + } + + //查询 + List list = baseDao.getList(params); + + return getPageData(list, page.getTotal(), SysUserDTO.class); + } + + @Override + public List list(Map params) { + //普通管理员,只能查询所属部门及子部门的数据 + UserDetail user = SecurityUser.getUser(); + if(user.getSuperAdmin() == SuperAdminEnum.NO.value()) { + params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId())); + } + + List entityList = baseDao.getList(params); + + return ConvertUtils.sourceToTarget(entityList, SysUserDTO.class); + } + + @Override + public SysUserDTO get(Long id) { + SysUserEntity entity = baseDao.getById(id); + + return ConvertUtils.sourceToTarget(entity, SysUserDTO.class); + } + + @Override + public SysUserDTO getByUsername(String username) { + SysUserEntity entity = baseDao.getByUsername(username); + return ConvertUtils.sourceToTarget(entity, SysUserDTO.class); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void save(SysUserDTO dto) { + SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class); + + //密码加密 + String password = PasswordUtils.encode(entity.getPassword()); + entity.setPassword(password); + + //保存用户 + entity.setSuperAdmin(SuperAdminEnum.NO.value()); + insert(entity); + + //保存角色用户关系 + sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysUserDTO dto) { + SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class); + + //密码加密 + if(StringUtils.isBlank(dto.getPassword())){ + entity.setPassword(null); + }else{ + String password = PasswordUtils.encode(entity.getPassword()); + entity.setPassword(password); + } + + //更新用户 + updateById(entity); + + //更新角色用户关系 + sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList()); + } + + @Override + public void delete(Long[] ids) { + //删除用户 + baseDao.deleteBatchIds(Arrays.asList(ids)); + + //删除角色用户关系 + sysRoleUserService.deleteByUserIds(ids); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updatePassword(Long id, String newPassword) { + newPassword = PasswordUtils.encode(newPassword); + + baseDao.updatePassword(id, newPassword); + } + + @Override + public int getCountByDeptId(Long deptId) { + return baseDao.getCountByDeptId(deptId); + } + + @Override + public List getUserIdListByDeptId(List deptIdList) { + return baseDao.getUserIdListByDeptId(deptIdList); + } + +} diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/AddressBookController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/AddressBookController.java new file mode 100644 index 0000000..dbf588b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/AddressBookController.java @@ -0,0 +1,116 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.AddressBookDTO; +import io.renren.modules.takeout.excel.AddressBookExcel; +import io.renren.modules.takeout.service.AddressBookService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 地址管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/addressbook") +@Api(tags="地址管理") +public class AddressBookController { + @Autowired + private AddressBookService addressBookService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:addressbook:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = addressBookService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:addressbook:info") + public Result get(@PathVariable("id") Long id){ + AddressBookDTO data = addressBookService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:addressbook:save") + public Result save(@RequestBody AddressBookDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + addressBookService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:addressbook:update") + public Result update(@RequestBody AddressBookDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + addressBookService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:addressbook:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + addressBookService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:addressbook:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = addressBookService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, AddressBookExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/CategoryController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/CategoryController.java new file mode 100644 index 0000000..8cc03f2 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/CategoryController.java @@ -0,0 +1,120 @@ +package io.renren.modules.takeout.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.front.bean.Category; +import io.renren.modules.front.utils.R; +import io.renren.modules.takeout.dto.CategoryDTO; +import io.renren.modules.takeout.entity.CategoryEntity; +import io.renren.modules.takeout.excel.CategoryExcel; +import io.renren.modules.takeout.service.CategoryService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 菜品及套餐分类 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/category") +@Api(tags="菜品及套餐分类") +public class CategoryController { + @Autowired + private CategoryService categoryService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:category:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = categoryService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:category:info") + public Result get(@PathVariable("id") Long id){ + CategoryDTO data = categoryService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:category:save") + public Result save(@RequestBody CategoryDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + categoryService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:category:update") + public Result update(@RequestBody CategoryDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + categoryService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:category:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + categoryService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:category:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = categoryService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, CategoryExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/DishController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/DishController.java new file mode 100644 index 0000000..6151b62 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/DishController.java @@ -0,0 +1,126 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.DishDTO; +import io.renren.modules.takeout.excel.DishExcel; +import io.renren.modules.takeout.service.DishService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 菜品管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/dish") +@Api(tags="菜品管理") +public class DishController { + @Autowired + private DishService dishService; + + @Autowired + private RedisTemplate redisTemplate; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:dish:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = dishService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:dish:info") + public Result get(@PathVariable("id") Long id){ + DishDTO data = dishService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:dish:save") + public Result save(@RequestBody DishDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + dishService.save(dto); + //清除当前分类下的菜品信息 + redisTemplate.delete("dish_" + dto.getCategoryId() + "_1"); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:dish:update") + public Result update(@RequestBody DishDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + dishService.update(dto); + //清除当前分类下的菜品信息 + redisTemplate.delete("dish_" + dto.getCategoryId() + "_1"); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:dish:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + dishService.delete(ids); + //清除所有的菜品缓存数据 + redisTemplate.delete("dish_*"); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:dish:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = dishService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, DishExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/DishFlavorController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/DishFlavorController.java new file mode 100644 index 0000000..91eddfb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/DishFlavorController.java @@ -0,0 +1,116 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.DishFlavorDTO; +import io.renren.modules.takeout.excel.DishFlavorExcel; +import io.renren.modules.takeout.service.DishFlavorService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 菜品口味关系表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/dishflavor") +@Api(tags="菜品口味关系表") +public class DishFlavorController { + @Autowired + private DishFlavorService dishFlavorService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:dishflavor:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = dishFlavorService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:dishflavor:info") + public Result get(@PathVariable("id") Long id){ + DishFlavorDTO data = dishFlavorService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:dishflavor:save") + public Result save(@RequestBody DishFlavorDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + dishFlavorService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:dishflavor:update") + public Result update(@RequestBody DishFlavorDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + dishFlavorService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:dishflavor:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + dishFlavorService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:dishflavor:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = dishFlavorService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, DishFlavorExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/OrderDetailController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/OrderDetailController.java new file mode 100644 index 0000000..746d5f7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/OrderDetailController.java @@ -0,0 +1,116 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.OrderDetailDTO; +import io.renren.modules.takeout.excel.OrderDetailExcel; +import io.renren.modules.takeout.service.OrderDetailService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 订单明细表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/orderdetail") +@Api(tags="订单明细表") +public class OrderDetailController { + @Autowired + private OrderDetailService orderDetailService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:orderdetail:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = orderDetailService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:orderdetail:info") + public Result get(@PathVariable("id") Long id){ + OrderDetailDTO data = orderDetailService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:orderdetail:save") + public Result save(@RequestBody OrderDetailDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + orderDetailService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:orderdetail:update") + public Result update(@RequestBody OrderDetailDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + orderDetailService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:orderdetail:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + orderDetailService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:orderdetail:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = orderDetailService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, OrderDetailExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/OrdersController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/OrdersController.java new file mode 100644 index 0000000..30da486 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/OrdersController.java @@ -0,0 +1,116 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.OrdersDTO; +import io.renren.modules.takeout.excel.OrdersExcel; +import io.renren.modules.takeout.service.OrdersService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 订单表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/orders") +@Api(tags="订单表") +public class OrdersController { + @Autowired + private OrdersService ordersService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:orders:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = ordersService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:orders:info") + public Result get(@PathVariable("id") Long id){ + OrdersDTO data = ordersService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:orders:save") + public Result save(@RequestBody OrdersDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + ordersService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:orders:update") + public Result update(@RequestBody OrdersDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + ordersService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:orders:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + ordersService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:orders:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = ordersService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, OrdersExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealController.java new file mode 100644 index 0000000..49a17e7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealController.java @@ -0,0 +1,120 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.SetmealDTO; +import io.renren.modules.takeout.excel.SetmealExcel; +import io.renren.modules.takeout.service.SetmealService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 套餐 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/setmeal") +@Api(tags="套餐") +public class SetmealController { + @Autowired + private SetmealService setmealService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:setmeal:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = setmealService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:setmeal:info") + public Result get(@PathVariable("id") Long id){ + SetmealDTO data = setmealService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:setmeal:save") + @CacheEvict(value = "setmealCache", allEntries = true) + public Result save(@RequestBody SetmealDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + setmealService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:setmeal:update") + @CacheEvict(value = "setmealCache", allEntries = true) + public Result update(@RequestBody SetmealDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + setmealService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:setmeal:delete") + @CacheEvict(value = "setmealCache", allEntries = true) + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + setmealService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:setmeal:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = setmealService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SetmealExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealDishController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealDishController.java new file mode 100644 index 0000000..d99f392 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/SetmealDishController.java @@ -0,0 +1,116 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.SetmealDishDTO; +import io.renren.modules.takeout.excel.SetmealDishExcel; +import io.renren.modules.takeout.service.SetmealDishService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 套餐菜品关系 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/setmealdish") +@Api(tags="套餐菜品关系") +public class SetmealDishController { + @Autowired + private SetmealDishService setmealDishService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:setmealdish:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = setmealDishService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:setmealdish:info") + public Result get(@PathVariable("id") Long id){ + SetmealDishDTO data = setmealDishService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:setmealdish:save") + public Result save(@RequestBody SetmealDishDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + setmealDishService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:setmealdish:update") + public Result update(@RequestBody SetmealDishDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + setmealDishService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:setmealdish:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + setmealDishService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:setmealdish:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = setmealDishService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, SetmealDishExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/ShoppingCartController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/ShoppingCartController.java new file mode 100644 index 0000000..898e92c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/ShoppingCartController.java @@ -0,0 +1,116 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.ShoppingCartDTO; +import io.renren.modules.takeout.excel.ShoppingCartExcel; +import io.renren.modules.takeout.service.ShoppingCartService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 购物车 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/shoppingcart") +@Api(tags="购物车") +public class ShoppingCartController { + @Autowired + private ShoppingCartService shoppingCartService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:shoppingcart:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = shoppingCartService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:shoppingcart:info") + public Result get(@PathVariable("id") Long id){ + ShoppingCartDTO data = shoppingCartService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:shoppingcart:save") + public Result save(@RequestBody ShoppingCartDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + shoppingCartService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:shoppingcart:update") + public Result update(@RequestBody ShoppingCartDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + shoppingCartService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:shoppingcart:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + shoppingCartService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:shoppingcart:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = shoppingCartService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, ShoppingCartExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/controller/UserController.java b/renren-admin/src/main/java/io/renren/modules/takeout/controller/UserController.java new file mode 100644 index 0000000..4e6257d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/controller/UserController.java @@ -0,0 +1,116 @@ +package io.renren.modules.takeout.controller; + +import io.renren.common.annotation.LogOperation; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.utils.ExcelUtils; +import io.renren.common.utils.Result; +import io.renren.common.validator.AssertUtils; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.DefaultGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.takeout.dto.UserDTO; +import io.renren.modules.takeout.excel.UserExcel; +import io.renren.modules.takeout.service.UserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + + +/** + * 用户信息 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@RestController +@RequestMapping("takeout/user") +@Api(tags="用户信息") +public class UserController { + @Autowired + private UserService userService; + + @GetMapping("page") + @ApiOperation("分页") + @ApiImplicitParams({ + @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", required = true, dataType="int") , + @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query",required = true, dataType="int") , + @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType="String") , + @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType="String") + }) + @RequiresPermissions("takeout:user:page") + public Result> page(@ApiIgnore @RequestParam Map params){ + PageData page = userService.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("takeout:user:info") + public Result get(@PathVariable("id") Long id){ + UserDTO data = userService.get(id); + + return new Result().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("takeout:user:save") + public Result save(@RequestBody UserDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + userService.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("takeout:user:update") + public Result update(@RequestBody UserDTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + userService.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("takeout:user:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + userService.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("takeout:user:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List list = userService.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, UserExcel.class); + } + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/AddressBookDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/AddressBookDao.java new file mode 100644 index 0000000..21a840d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/AddressBookDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.AddressBookEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 地址管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface AddressBookDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/CategoryDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/CategoryDao.java new file mode 100644 index 0000000..9063688 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/CategoryDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.CategoryEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 菜品及套餐分类 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface CategoryDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/DishDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/DishDao.java new file mode 100644 index 0000000..824c3f3 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/DishDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.DishEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 菜品管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface DishDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/DishFlavorDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/DishFlavorDao.java new file mode 100644 index 0000000..5d53c81 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/DishFlavorDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.DishFlavorEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 菜品口味关系表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface DishFlavorDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/OrderDetailDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/OrderDetailDao.java new file mode 100644 index 0000000..f0faeac --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/OrderDetailDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.OrderDetailEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 订单明细表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface OrderDetailDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/OrdersDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/OrdersDao.java new file mode 100644 index 0000000..67ee029 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/OrdersDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.OrdersEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 订单表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface OrdersDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDao.java new file mode 100644 index 0000000..942f3be --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.SetmealEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 套餐 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface SetmealDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDishDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDishDao.java new file mode 100644 index 0000000..429aefb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/SetmealDishDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.SetmealDishEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 套餐菜品关系 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface SetmealDishDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/ShoppingCartDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/ShoppingCartDao.java new file mode 100644 index 0000000..3fcd570 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/ShoppingCartDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.ShoppingCartEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 购物车 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface ShoppingCartDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dao/UserDao.java b/renren-admin/src/main/java/io/renren/modules/takeout/dao/UserDao.java new file mode 100644 index 0000000..74c54d4 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dao/UserDao.java @@ -0,0 +1,16 @@ +package io.renren.modules.takeout.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.modules.takeout.entity.UserEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户信息 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Mapper +public interface UserDao extends BaseDao { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/AddressBookDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/AddressBookDTO.java new file mode 100644 index 0000000..6a83b4c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/AddressBookDTO.java @@ -0,0 +1,80 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + + +/** + * 地址管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "地址管理") +public class AddressBookDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "用户id") + private Long userId; + + @ApiModelProperty(value = "收货人") + private String consignee; + + @ApiModelProperty(value = "性别 0 男 1 女") + private Integer gender; + + @ApiModelProperty(value = "手机号") + private String phone; + + @ApiModelProperty(value = "省级区划编号") + private String provinceCode; + + @ApiModelProperty(value = "省级名称") + private String provinceName; + + @ApiModelProperty(value = "市级区划编号") + private String cityCode; + + @ApiModelProperty(value = "市级名称") + private String cityName; + + @ApiModelProperty(value = "区级区划编号") + private String districtCode; + + @ApiModelProperty(value = "区级名称") + private String districtName; + + @ApiModelProperty(value = "详细地址") + private String detail; + + @ApiModelProperty(value = "标签") + private String label; + + @ApiModelProperty(value = "默认 0 否 1是") + private Integer isDefault; + + @ApiModelProperty(value = "创建人") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "修改人") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + @ApiModelProperty(value = "是否删除") + private Integer isDeleted; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/CategoryDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/CategoryDTO.java new file mode 100644 index 0000000..6930949 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/CategoryDTO.java @@ -0,0 +1,47 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + + +/** + * 菜品及套餐分类 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "菜品及套餐分类") +public class CategoryDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "类型 1 菜品分类 2 套餐分类") + private Integer type; + + @ApiModelProperty(value = "分类名称") + private String name; + + @ApiModelProperty(value = "顺序") + private Integer sort; + + @ApiModelProperty(value = "创建人") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "修改人") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/DishDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/DishDTO.java new file mode 100644 index 0000000..ece2ff4 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/DishDTO.java @@ -0,0 +1,65 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 菜品管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "菜品管理") +public class DishDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "菜品名称") + private String name; + + @ApiModelProperty(value = "菜品分类id") + private Long categoryId; + + @ApiModelProperty(value = "菜品价格") + private BigDecimal price; + + @ApiModelProperty(value = "商品码") + private String code; + + @ApiModelProperty(value = "图片") + private String image; + + @ApiModelProperty(value = "描述信息") + private String description; + + @ApiModelProperty(value = "0 停售 1 起售") + private Integer status; + + @ApiModelProperty(value = "顺序") + private Integer sort; + + @ApiModelProperty(value = "创建人") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "修改人") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + @ApiModelProperty(value = "是否删除") + private Integer isDeleted; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/DishFlavorDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/DishFlavorDTO.java new file mode 100644 index 0000000..e8e221f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/DishFlavorDTO.java @@ -0,0 +1,50 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + + +/** + * 菜品口味关系表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "菜品口味关系表") +public class DishFlavorDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "菜品") + private Long dishId; + + @ApiModelProperty(value = "口味名称") + private String name; + + @ApiModelProperty(value = "口味数据list") + private String value; + + @ApiModelProperty(value = "创建人") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "修改人") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + @ApiModelProperty(value = "是否删除") + private Integer isDeleted; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/OrderDetailDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/OrderDetailDTO.java new file mode 100644 index 0000000..3fa7ec8 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/OrderDetailDTO.java @@ -0,0 +1,49 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * 订单明细表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "订单明细表") +public class OrderDetailDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "名字") + private String name; + + @ApiModelProperty(value = "图片") + private String image; + + @ApiModelProperty(value = "订单id") + private Long orderId; + + @ApiModelProperty(value = "菜品id") + private Long dishId; + + @ApiModelProperty(value = "套餐id") + private Long setmealId; + + @ApiModelProperty(value = "口味") + private String dishFlavor; + + @ApiModelProperty(value = "数量") + private Integer number; + + @ApiModelProperty(value = "金额") + private BigDecimal amount; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/OrdersDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/OrdersDTO.java new file mode 100644 index 0000000..cd65d57 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/OrdersDTO.java @@ -0,0 +1,65 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 订单表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "订单表") +public class OrdersDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "订单号") + private String number; + + @ApiModelProperty(value = "订单状态 1待付款,2待派送,3已派送,4已完成,5已取消") + private Integer status; + + @ApiModelProperty(value = "下单用户") + private Long userId; + + @ApiModelProperty(value = "地址id") + private Long addressBookId; + + @ApiModelProperty(value = "下单时间") + private Date orderTime; + + @ApiModelProperty(value = "结账时间") + private Date checkoutTime; + + @ApiModelProperty(value = "支付方式 1微信,2支付宝") + private Integer payMethod; + + @ApiModelProperty(value = "实收金额") + private BigDecimal amount; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "") + private String phone; + + @ApiModelProperty(value = "") + private String address; + + @ApiModelProperty(value = "") + private String userName; + + @ApiModelProperty(value = "") + private String consignee; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDTO.java new file mode 100644 index 0000000..cf7d727 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDTO.java @@ -0,0 +1,62 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 套餐 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "套餐") +public class SetmealDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "菜品分类id") + private Long categoryId; + + @ApiModelProperty(value = "套餐名称") + private String name; + + @ApiModelProperty(value = "套餐价格") + private BigDecimal price; + + @ApiModelProperty(value = "状态 0:停用 1:启用") + private Integer status; + + @ApiModelProperty(value = "编码") + private String code; + + @ApiModelProperty(value = "描述信息") + private String description; + + @ApiModelProperty(value = "图片") + private String image; + + @ApiModelProperty(value = "创建人") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "修改人") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + @ApiModelProperty(value = "是否删除") + private Integer isDeleted; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDishDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDishDTO.java new file mode 100644 index 0000000..3ecc8f4 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/SetmealDishDTO.java @@ -0,0 +1,59 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 套餐菜品关系 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "套餐菜品关系") +public class SetmealDishDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "套餐id ") + private String setmealId; + + @ApiModelProperty(value = "菜品id") + private String dishId; + + @ApiModelProperty(value = "菜品名称 (冗余字段)") + private String name; + + @ApiModelProperty(value = "菜品原价(冗余字段)") + private BigDecimal price; + + @ApiModelProperty(value = "份数") + private Integer copies; + + @ApiModelProperty(value = "排序") + private Integer sort; + + @ApiModelProperty(value = "创建人") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "修改人") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + @ApiModelProperty(value = "是否删除") + private Integer isDeleted; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/ShoppingCartDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/ShoppingCartDTO.java new file mode 100644 index 0000000..692420d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/ShoppingCartDTO.java @@ -0,0 +1,62 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 购物车 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "购物车") +public class ShoppingCartDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "名称") + private String name; + + @ApiModelProperty(value = "图片") + private String image; + + @ApiModelProperty(value = "主键") + private Long userId; + + @ApiModelProperty(value = "菜品id") + private Long dishId; + + @ApiModelProperty(value = "套餐id") + private Long setmealId; + + @ApiModelProperty(value = "口味") + private String dishFlavor; + + @ApiModelProperty(value = "数量") + private Integer number; + + @ApiModelProperty(value = "金额") + private BigDecimal amount; + + @ApiModelProperty(value = "创建者") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "更新者") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/dto/UserDTO.java b/renren-admin/src/main/java/io/renren/modules/takeout/dto/UserDTO.java new file mode 100644 index 0000000..832aab0 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/dto/UserDTO.java @@ -0,0 +1,62 @@ +package io.renren.modules.takeout.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + + +/** + * 用户信息 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@ApiModel(value = "用户信息") +public class UserDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "姓名") + private String name; + + @ApiModelProperty(value = "手机号") + private String phone; + + @ApiModelProperty(value = "性别 0:男 1:女 2:保密") + private Integer gender; + + @ApiModelProperty(value = "身份证号") + private String idNumber; + + @ApiModelProperty(value = "头像") + private String avatarUrl; + + @ApiModelProperty(value = "状态 0:禁用,1:正常") + private Integer status; + + @ApiModelProperty(value = "微信openid") + private String openid; + + @ApiModelProperty(value = "微信昵称") + private String nickName; + + @ApiModelProperty(value = "创建者") + private Long creator; + + @ApiModelProperty(value = "创建时间") + private Date createDate; + + @ApiModelProperty(value = "更新者") + private Long updater; + + @ApiModelProperty(value = "更新时间") + private Date updateDate; + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/AddressBookEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/AddressBookEntity.java new file mode 100644 index 0000000..c7a5d1a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/AddressBookEntity.java @@ -0,0 +1,94 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * 地址管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("address_book") +public class AddressBookEntity { + + /** + * 主键 + */ + private Long id; + /** + * 用户id + */ + private Long userId; + /** + * 收货人 + */ + private String consignee; + /** + * 性别 0 男 1 女 + */ + private Integer gender; + /** + * 手机号 + */ + private String phone; + /** + * 省级区划编号 + */ + private String provinceCode; + /** + * 省级名称 + */ + private String provinceName; + /** + * 市级区划编号 + */ + private String cityCode; + /** + * 市级名称 + */ + private String cityName; + /** + * 区级区划编号 + */ + private String districtCode; + /** + * 区级名称 + */ + private String districtName; + /** + * 详细地址 + */ + private String detail; + /** + * 标签 + */ + private String label; + /** + * 默认 0 否 1是 + */ + private Integer isDefault; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 是否删除 + */ + private Integer isDeleted; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/CategoryEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/CategoryEntity.java new file mode 100644 index 0000000..a23ca27 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/CategoryEntity.java @@ -0,0 +1,50 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * 菜品及套餐分类 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("category") +public class CategoryEntity { + + /** + * 主键 + */ + private Long id; + /** + * 类型 1 菜品分类 2 套餐分类 + */ + private Integer type; + /** + * 分类名称 + */ + private String name; + /** + * 顺序 + */ + private Integer sort; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/DishEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/DishEntity.java new file mode 100644 index 0000000..1163bf9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/DishEntity.java @@ -0,0 +1,75 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 菜品管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("dish") +public class DishEntity { + + /** + * 主键 + */ + private Long id; + /** + * 菜品名称 + */ + private String name; + /** + * 菜品分类id + */ + private Long categoryId; + /** + * 菜品价格 + */ + private BigDecimal price; + /** + * 商品码 + */ + private String code; + /** + * 图片 + */ + private String image; + /** + * 描述信息 + */ + private String description; + /** + * 0 停售 1 起售 + */ + private Integer status; + /** + * 顺序 + */ + private Integer sort; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 是否删除 + */ + private Integer isDeleted; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/DishFlavorEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/DishFlavorEntity.java new file mode 100644 index 0000000..7289a76 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/DishFlavorEntity.java @@ -0,0 +1,54 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * 菜品口味关系表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("dish_flavor") +public class DishFlavorEntity { + + /** + * 主键 + */ + private Long id; + /** + * 菜品 + */ + private Long dishId; + /** + * 口味名称 + */ + private String name; + /** + * 口味数据list + */ + private String value; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 是否删除 + */ + private Integer isDeleted; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/OrderDetailEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/OrderDetailEntity.java new file mode 100644 index 0000000..e25739a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/OrderDetailEntity.java @@ -0,0 +1,54 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 订单明细表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("order_detail") +public class OrderDetailEntity { + + /** + * 主键 + */ + private Long id; + /** + * 名字 + */ + private String name; + /** + * 图片 + */ + private String image; + /** + * 订单id + */ + private Long orderId; + /** + * 菜品id + */ + private Long dishId; + /** + * 套餐id + */ + private Long setmealId; + /** + * 口味 + */ + private String dishFlavor; + /** + * 数量 + */ + private Integer number; + /** + * 金额 + */ + private BigDecimal amount; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/OrdersEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/OrdersEntity.java new file mode 100644 index 0000000..d6f7d90 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/OrdersEntity.java @@ -0,0 +1,75 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 订单表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("orders") +public class OrdersEntity { + + /** + * 主键 + */ + private Long id; + /** + * 订单号 + */ + private String number; + /** + * 订单状态 1待付款,2待派送,3已派送,4已完成,5已取消 + */ + private Integer status; + /** + * 下单用户 + */ + private Long userId; + /** + * 地址id + */ + private Long addressBookId; + /** + * 下单时间 + */ + private Date orderTime; + /** + * 结账时间 + */ + private Date checkoutTime; + /** + * 支付方式 1微信,2支付宝 + */ + private Integer payMethod; + /** + * 实收金额 + */ + private BigDecimal amount; + /** + * 备注 + */ + private String remark; + /** + * + */ + private String phone; + /** + * + */ + private String address; + /** + * + */ + private String userName; + /** + * + */ + private String consignee; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealDishEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealDishEntity.java new file mode 100644 index 0000000..6e9593b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealDishEntity.java @@ -0,0 +1,67 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 套餐菜品关系 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("setmeal_dish") +public class SetmealDishEntity { + + /** + * 主键 + */ + private Long id; + /** + * 套餐id + */ + private String setmealId; + /** + * 菜品id + */ + private String dishId; + /** + * 菜品名称 (冗余字段) + */ + private String name; + /** + * 菜品原价(冗余字段) + */ + private BigDecimal price; + /** + * 份数 + */ + private Integer copies; + /** + * 排序 + */ + private Integer sort; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 是否删除 + */ + private Integer isDeleted; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealEntity.java new file mode 100644 index 0000000..b943197 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/SetmealEntity.java @@ -0,0 +1,71 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 套餐 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("setmeal") +public class SetmealEntity { + + /** + * 主键 + */ + private Long id; + /** + * 菜品分类id + */ + private Long categoryId; + /** + * 套餐名称 + */ + private String name; + /** + * 套餐价格 + */ + private BigDecimal price; + /** + * 状态 0:停用 1:启用 + */ + private Integer status; + /** + * 编码 + */ + private String code; + /** + * 描述信息 + */ + private String description; + /** + * 图片 + */ + private String image; + /** + * 创建人 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 修改人 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; + /** + * 是否删除 + */ + private Integer isDeleted; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/ShoppingCartEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/ShoppingCartEntity.java new file mode 100644 index 0000000..6139e34 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/ShoppingCartEntity.java @@ -0,0 +1,71 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 购物车 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("shopping_cart") +public class ShoppingCartEntity { + + /** + * 主键 + */ + private Long id; + /** + * 名称 + */ + private String name; + /** + * 图片 + */ + private String image; + /** + * 主键 + */ + private Long userId; + /** + * 菜品id + */ + private Long dishId; + /** + * 套餐id + */ + private Long setmealId; + /** + * 口味 + */ + private String dishFlavor; + /** + * 数量 + */ + private Integer number; + /** + * 金额 + */ + private BigDecimal amount; + /** + * 创建者 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 更新者 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/entity/UserEntity.java b/renren-admin/src/main/java/io/renren/modules/takeout/entity/UserEntity.java new file mode 100644 index 0000000..d304b8f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/entity/UserEntity.java @@ -0,0 +1,70 @@ +package io.renren.modules.takeout.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * 用户信息 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +@TableName("user") +public class UserEntity { + + /** + * id + */ + private Long id; + /** + * 姓名 + */ + private String name; + /** + * 手机号 + */ + private String phone; + /** + * 性别 0:男 1:女 2:保密 + */ + private Integer gender; + /** + * 身份证号 + */ + private String idNumber; + /** + * 头像 + */ + private String avatarUrl; + /** + * 状态 0:禁用,1:正常 + */ + private Integer status; + /** + * 微信openid + */ + private String openid; + /** + * 微信昵称 + */ + private String nickName; + /** + * 创建者 + */ + private Long creator; + /** + * 创建时间 + */ + private Date createDate; + /** + * 更新者 + */ + private Long updater; + /** + * 更新时间 + */ + private Date updateDate; +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/AddressBookExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/AddressBookExcel.java new file mode 100644 index 0000000..328c548 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/AddressBookExcel.java @@ -0,0 +1,55 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 地址管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class AddressBookExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "用户id") + private Long userId; + @Excel(name = "收货人") + private String consignee; + @Excel(name = "性别 0 男 1 女") + private Integer gender; + @Excel(name = "手机号") + private String phone; + @Excel(name = "省级区划编号") + private String provinceCode; + @Excel(name = "省级名称") + private String provinceName; + @Excel(name = "市级区划编号") + private String cityCode; + @Excel(name = "市级名称") + private String cityName; + @Excel(name = "区级区划编号") + private String districtCode; + @Excel(name = "区级名称") + private String districtName; + @Excel(name = "详细地址") + private String detail; + @Excel(name = "标签") + private String label; + @Excel(name = "默认 0 否 1是") + private Integer isDefault; + @Excel(name = "创建人") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "修改人") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + @Excel(name = "是否删除") + private Integer isDeleted; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/CategoryExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/CategoryExcel.java new file mode 100644 index 0000000..ea87b94 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/CategoryExcel.java @@ -0,0 +1,33 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 菜品及套餐分类 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class CategoryExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "类型 1 菜品分类 2 套餐分类") + private Integer type; + @Excel(name = "分类名称") + private String name; + @Excel(name = "顺序") + private Integer sort; + @Excel(name = "创建人") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "修改人") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/DishExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/DishExcel.java new file mode 100644 index 0000000..d360b2c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/DishExcel.java @@ -0,0 +1,46 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 菜品管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class DishExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "菜品名称") + private String name; + @Excel(name = "菜品分类id") + private Long categoryId; + @Excel(name = "菜品价格") + private BigDecimal price; + @Excel(name = "商品码") + private String code; + @Excel(name = "图片") + private String image; + @Excel(name = "描述信息") + private String description; + @Excel(name = "0 停售 1 起售") + private Integer status; + @Excel(name = "顺序") + private Integer sort; + @Excel(name = "创建人") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "修改人") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + @Excel(name = "是否删除") + private Integer isDeleted; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/DishFlavorExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/DishFlavorExcel.java new file mode 100644 index 0000000..ff05544 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/DishFlavorExcel.java @@ -0,0 +1,35 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 菜品口味关系表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class DishFlavorExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "菜品") + private Long dishId; + @Excel(name = "口味名称") + private String name; + @Excel(name = "口味数据list") + private String value; + @Excel(name = "创建人") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "修改人") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + @Excel(name = "是否删除") + private Integer isDeleted; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/OrderDetailExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/OrderDetailExcel.java new file mode 100644 index 0000000..ff119f7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/OrderDetailExcel.java @@ -0,0 +1,35 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 订单明细表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class OrderDetailExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "名字") + private String name; + @Excel(name = "图片") + private String image; + @Excel(name = "订单id") + private Long orderId; + @Excel(name = "菜品id") + private Long dishId; + @Excel(name = "套餐id") + private Long setmealId; + @Excel(name = "口味") + private String dishFlavor; + @Excel(name = "数量") + private Integer number; + @Excel(name = "金额") + private BigDecimal amount; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/OrdersExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/OrdersExcel.java new file mode 100644 index 0000000..ab47c74 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/OrdersExcel.java @@ -0,0 +1,46 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 订单表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class OrdersExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "订单号") + private String number; + @Excel(name = "订单状态 1待付款,2待派送,3已派送,4已完成,5已取消") + private Integer status; + @Excel(name = "下单用户") + private Long userId; + @Excel(name = "地址id") + private Long addressBookId; + @Excel(name = "下单时间") + private Date orderTime; + @Excel(name = "结账时间") + private Date checkoutTime; + @Excel(name = "支付方式 1微信,2支付宝") + private Integer payMethod; + @Excel(name = "实收金额") + private BigDecimal amount; + @Excel(name = "备注") + private String remark; + @Excel(name = "") + private String phone; + @Excel(name = "") + private String address; + @Excel(name = "") + private String userName; + @Excel(name = "") + private String consignee; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealDishExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealDishExcel.java new file mode 100644 index 0000000..3a91863 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealDishExcel.java @@ -0,0 +1,42 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 套餐菜品关系 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class SetmealDishExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "套餐id ") + private String setmealId; + @Excel(name = "菜品id") + private String dishId; + @Excel(name = "菜品名称 (冗余字段)") + private String name; + @Excel(name = "菜品原价(冗余字段)") + private BigDecimal price; + @Excel(name = "份数") + private Integer copies; + @Excel(name = "排序") + private Integer sort; + @Excel(name = "创建人") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "修改人") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + @Excel(name = "是否删除") + private Integer isDeleted; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealExcel.java new file mode 100644 index 0000000..376a473 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/SetmealExcel.java @@ -0,0 +1,44 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 套餐 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class SetmealExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "菜品分类id") + private Long categoryId; + @Excel(name = "套餐名称") + private String name; + @Excel(name = "套餐价格") + private BigDecimal price; + @Excel(name = "状态 0:停用 1:启用") + private Integer status; + @Excel(name = "编码") + private String code; + @Excel(name = "描述信息") + private String description; + @Excel(name = "图片") + private String image; + @Excel(name = "创建人") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "修改人") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + @Excel(name = "是否删除") + private Integer isDeleted; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/ShoppingCartExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/ShoppingCartExcel.java new file mode 100644 index 0000000..2239cd7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/ShoppingCartExcel.java @@ -0,0 +1,44 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 购物车 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class ShoppingCartExcel { + @Excel(name = "主键") + private Long id; + @Excel(name = "名称") + private String name; + @Excel(name = "图片") + private String image; + @Excel(name = "主键") + private Long userId; + @Excel(name = "菜品id") + private Long dishId; + @Excel(name = "套餐id") + private Long setmealId; + @Excel(name = "口味") + private String dishFlavor; + @Excel(name = "数量") + private Integer number; + @Excel(name = "金额") + private BigDecimal amount; + @Excel(name = "创建者") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "更新者") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/excel/UserExcel.java b/renren-admin/src/main/java/io/renren/modules/takeout/excel/UserExcel.java new file mode 100644 index 0000000..dc833f9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/excel/UserExcel.java @@ -0,0 +1,43 @@ +package io.renren.modules.takeout.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +import java.util.Date; + +/** + * 用户信息 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Data +public class UserExcel { + @Excel(name = "id") + private Long id; + @Excel(name = "姓名") + private String name; + @Excel(name = "手机号") + private String phone; + @Excel(name = "性别 0:男 1:女 2:保密") + private Integer gender; + @Excel(name = "身份证号") + private String idNumber; + @Excel(name = "头像") + private String avatarUrl; + @Excel(name = "状态 0:禁用,1:正常") + private Integer status; + @Excel(name = "微信openid") + private String openid; + @Excel(name = "微信昵称") + private String nickName; + @Excel(name = "创建者") + private Long creator; + @Excel(name = "创建时间") + private Date createDate; + @Excel(name = "更新者") + private Long updater; + @Excel(name = "更新时间") + private Date updateDate; + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/AddressBookService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/AddressBookService.java new file mode 100644 index 0000000..00de373 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/AddressBookService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.AddressBookDTO; +import io.renren.modules.takeout.entity.AddressBookEntity; + +/** + * 地址管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface AddressBookService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/CategoryService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/CategoryService.java new file mode 100644 index 0000000..6ba7364 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/CategoryService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.CategoryDTO; +import io.renren.modules.takeout.entity.CategoryEntity; + +/** + * 菜品及套餐分类 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface CategoryService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/DishFlavorService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/DishFlavorService.java new file mode 100644 index 0000000..ca6108b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/DishFlavorService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.DishFlavorDTO; +import io.renren.modules.takeout.entity.DishFlavorEntity; + +/** + * 菜品口味关系表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface DishFlavorService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/DishService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/DishService.java new file mode 100644 index 0000000..9fc0d93 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/DishService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.DishDTO; +import io.renren.modules.takeout.entity.DishEntity; + +/** + * 菜品管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface DishService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/OrderDetailService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/OrderDetailService.java new file mode 100644 index 0000000..936644d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/OrderDetailService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.OrderDetailDTO; +import io.renren.modules.takeout.entity.OrderDetailEntity; + +/** + * 订单明细表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface OrderDetailService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/OrdersService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/OrdersService.java new file mode 100644 index 0000000..aa2b5bd --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/OrdersService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.OrdersDTO; +import io.renren.modules.takeout.entity.OrdersEntity; + +/** + * 订单表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface OrdersService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealDishService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealDishService.java new file mode 100644 index 0000000..c582b0a --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealDishService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.SetmealDishDTO; +import io.renren.modules.takeout.entity.SetmealDishEntity; + +/** + * 套餐菜品关系 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface SetmealDishService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealService.java new file mode 100644 index 0000000..58f1cfb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/SetmealService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.SetmealDTO; +import io.renren.modules.takeout.entity.SetmealEntity; + +/** + * 套餐 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface SetmealService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/ShoppingCartService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/ShoppingCartService.java new file mode 100644 index 0000000..860bcee --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/ShoppingCartService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.ShoppingCartDTO; +import io.renren.modules.takeout.entity.ShoppingCartEntity; + +/** + * 购物车 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface ShoppingCartService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/UserService.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/UserService.java new file mode 100644 index 0000000..93f103f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/UserService.java @@ -0,0 +1,15 @@ +package io.renren.modules.takeout.service; + +import io.renren.common.service.CrudService; +import io.renren.modules.takeout.dto.UserDTO; +import io.renren.modules.takeout.entity.UserEntity; + +/** + * 用户信息 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +public interface UserService extends CrudService { + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/AddressBookServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/AddressBookServiceImpl.java new file mode 100644 index 0000000..00bc88c --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/AddressBookServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.AddressBookDao; +import io.renren.modules.takeout.dto.AddressBookDTO; +import io.renren.modules.takeout.entity.AddressBookEntity; +import io.renren.modules.takeout.service.AddressBookService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 地址管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class AddressBookServiceImpl extends CrudServiceImpl implements AddressBookService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/CategoryServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/CategoryServiceImpl.java new file mode 100644 index 0000000..defa849 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/CategoryServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.CategoryDao; +import io.renren.modules.takeout.dto.CategoryDTO; +import io.renren.modules.takeout.entity.CategoryEntity; +import io.renren.modules.takeout.service.CategoryService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 菜品及套餐分类 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class CategoryServiceImpl extends CrudServiceImpl implements CategoryService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishFlavorServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishFlavorServiceImpl.java new file mode 100644 index 0000000..b9b3f8d --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishFlavorServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.DishFlavorDao; +import io.renren.modules.takeout.dto.DishFlavorDTO; +import io.renren.modules.takeout.entity.DishFlavorEntity; +import io.renren.modules.takeout.service.DishFlavorService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 菜品口味关系表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class DishFlavorServiceImpl extends CrudServiceImpl implements DishFlavorService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishServiceImpl.java new file mode 100644 index 0000000..475a0a6 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/DishServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.DishDao; +import io.renren.modules.takeout.dto.DishDTO; +import io.renren.modules.takeout.entity.DishEntity; +import io.renren.modules.takeout.service.DishService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 菜品管理 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class DishServiceImpl extends CrudServiceImpl implements DishService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrderDetailServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrderDetailServiceImpl.java new file mode 100644 index 0000000..ad811c9 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrderDetailServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.OrderDetailDao; +import io.renren.modules.takeout.dto.OrderDetailDTO; +import io.renren.modules.takeout.entity.OrderDetailEntity; +import io.renren.modules.takeout.service.OrderDetailService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 订单明细表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class OrderDetailServiceImpl extends CrudServiceImpl implements OrderDetailService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrdersServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrdersServiceImpl.java new file mode 100644 index 0000000..87677ac --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/OrdersServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.OrdersDao; +import io.renren.modules.takeout.dto.OrdersDTO; +import io.renren.modules.takeout.entity.OrdersEntity; +import io.renren.modules.takeout.service.OrdersService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 订单表 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class OrdersServiceImpl extends CrudServiceImpl implements OrdersService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealDishServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealDishServiceImpl.java new file mode 100644 index 0000000..155eb4b --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealDishServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.SetmealDishDao; +import io.renren.modules.takeout.dto.SetmealDishDTO; +import io.renren.modules.takeout.entity.SetmealDishEntity; +import io.renren.modules.takeout.service.SetmealDishService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 套餐菜品关系 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class SetmealDishServiceImpl extends CrudServiceImpl implements SetmealDishService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealServiceImpl.java new file mode 100644 index 0000000..c3cc0c7 --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/SetmealServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.SetmealDao; +import io.renren.modules.takeout.dto.SetmealDTO; +import io.renren.modules.takeout.entity.SetmealEntity; +import io.renren.modules.takeout.service.SetmealService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 套餐 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class SetmealServiceImpl extends CrudServiceImpl implements SetmealService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/ShoppingCartServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/ShoppingCartServiceImpl.java new file mode 100644 index 0000000..a911abb --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/ShoppingCartServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.ShoppingCartDao; +import io.renren.modules.takeout.dto.ShoppingCartDTO; +import io.renren.modules.takeout.entity.ShoppingCartEntity; +import io.renren.modules.takeout.service.ShoppingCartService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 购物车 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class ShoppingCartServiceImpl extends CrudServiceImpl implements ShoppingCartService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/UserServiceImpl.java b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..072b81f --- /dev/null +++ b/renren-admin/src/main/java/io/renren/modules/takeout/service/impl/UserServiceImpl.java @@ -0,0 +1,34 @@ +package io.renren.modules.takeout.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import io.renren.common.service.impl.CrudServiceImpl; +import io.renren.modules.takeout.dao.UserDao; +import io.renren.modules.takeout.dto.UserDTO; +import io.renren.modules.takeout.entity.UserEntity; +import io.renren.modules.takeout.service.UserService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * 用户信息 + * + * @author zyx + * @since 1.0.0 2023-06-09 + */ +@Service +public class UserServiceImpl extends CrudServiceImpl implements UserService { + + @Override + public QueryWrapper getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-admin/src/main/resources/application-dev.yml b/renren-admin/src/main/resources/application-dev.yml new file mode 100644 index 0000000..d0353bb --- /dev/null +++ b/renren-admin/src/main/resources/application-dev.yml @@ -0,0 +1,69 @@ +spring: + datasource: + druid: + #MySQL + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/mt_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: root + password: zyx007 + #达梦8 +# driver-class-name: dm.jdbc.driver.DmDriver +# url: jdbc:dm://192.168.10.10:5236/renren_security?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true +# username: renren_security +# password: 12345678 + # #Oracle + # driver-class-name: oracle.jdbc.OracleDriver + # url: jdbc:oracle:thin:@192.168.10.10:1521:xe + # username: renren_security + # password: 123456 + # #SQLServer + # driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver + # url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security + # username: sa + # password: 123456 + # #postgresql + # driver-class-name: org.postgresql.Driver + # url: jdbc:postgresql://192.168.10.10:5432/postgres + # username: postgres + # password: 123456 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 6000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + # validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + #login-username: admin + #login-password: admin + #达梦数据库,需要注释掉,其他数据库可以打开 +# filter: +# stat: +# log-slow-sql: true +# slow-sql-millis: 1000 +# merge-sql: false +# wall: +# config: +# multi-statement-allow: true + +##多数据源的配置,需要引用renren-dynamic-datasource +#dynamic: +# datasource: +# slave1: +# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver +# url: jdbc:sqlserver://123456:1433;DatabaseName=renren_security +# username: sa +# password: 123456 +# slave2: +# driver-class-name: org.postgresql.Driver +# url: jdbc:postgresql://123456:5432/renren_security +# username: postgres +# password: 123456 \ No newline at end of file diff --git a/renren-admin/src/main/resources/application-prod.yml b/renren-admin/src/main/resources/application-prod.yml new file mode 100644 index 0000000..80d85af --- /dev/null +++ b/renren-admin/src/main/resources/application-prod.yml @@ -0,0 +1,34 @@ +spring: + datasource: + druid: + #MySQL + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/renren_security?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: renren + password: 123456 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 60000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + #login-username: admin + #login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true \ No newline at end of file diff --git a/renren-admin/src/main/resources/application-test.yml b/renren-admin/src/main/resources/application-test.yml new file mode 100644 index 0000000..80d85af --- /dev/null +++ b/renren-admin/src/main/resources/application-test.yml @@ -0,0 +1,34 @@ +spring: + datasource: + druid: + #MySQL + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/renren_security?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: renren + password: 123456 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 60000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + #login-username: admin + #login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true \ No newline at end of file diff --git a/renren-admin/src/main/resources/application.yml b/renren-admin/src/main/resources/application.yml new file mode 100644 index 0000000..ad5db56 --- /dev/null +++ b/renren-admin/src/main/resources/application.yml @@ -0,0 +1,83 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + threads: + max: 1000 + min-spare: 30 + port: 8080 + servlet: + context-path: /api + session: + cookie: + http-only: true + +knife4j: + enable: true + basic: + enable: false + username: admin + password: admin + setting: + enableFooter: false + +spring: + # 环境 dev|test|prod + profiles: + active: dev + messages: + encoding: UTF-8 + basename: i18n/messages + mvc: + pathmatch: + matching-strategy: ANT_PATH_MATCHER + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + enabled: true + redis: + database: 0 + host: localhost + port: 6379 + password: # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + +# 是否开启redis缓存 true开启 false关闭 +renren: + redis: + open: true + +#mybatis +mybatis-plus: + mapper-locations: classpath*:/mapper/**/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: io.renren.modules.*.entity + global-config: + #数据库相关配置 + db-config: + #主键类型 + id-type: ASSIGN_ID + banner: false + #原生配置 + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + configuration-properties: + prefix: + blobType: BLOB + boolValue: TRUE + +#用于发送邮箱验证码的账户和密码 +email: + #qq + userName: 1029606625@qq.com + password: gohqyjaowyfnbcjf \ No newline at end of file diff --git a/renren-admin/src/main/resources/banner.txt b/renren-admin/src/main/resources/banner.txt new file mode 100644 index 0000000..d9219dd --- /dev/null +++ b/renren-admin/src/main/resources/banner.txt @@ -0,0 +1,5 @@ +==================================================================================================================== + + 欢迎使用 renren-security - Powered By https://www.renren.io + +==================================================================================================================== \ No newline at end of file diff --git a/renren-admin/src/main/resources/logback-spring.xml b/renren-admin/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..5deef21 --- /dev/null +++ b/renren-admin/src/main/resources/logback-spring.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/job/ScheduleJobDao.xml b/renren-admin/src/main/resources/mapper/job/ScheduleJobDao.xml new file mode 100644 index 0000000..d53d9e2 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/job/ScheduleJobDao.xml @@ -0,0 +1,14 @@ + + + + + + + + update schedule_job set status = #{status} where id in + + #{id} + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/job/ScheduleJobLogDao.xml b/renren-admin/src/main/resources/mapper/job/ScheduleJobLogDao.xml new file mode 100644 index 0000000..6999238 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/job/ScheduleJobLogDao.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/log/SysLogErrorDao.xml b/renren-admin/src/main/resources/mapper/log/SysLogErrorDao.xml new file mode 100644 index 0000000..27268c5 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/log/SysLogErrorDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/log/SysLogLoginDao.xml b/renren-admin/src/main/resources/mapper/log/SysLogLoginDao.xml new file mode 100644 index 0000000..ab6ec35 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/log/SysLogLoginDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/log/SysLogOperationDao.xml b/renren-admin/src/main/resources/mapper/log/SysLogOperationDao.xml new file mode 100644 index 0000000..079abc0 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/log/SysLogOperationDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/oss/SysOssDao.xml b/renren-admin/src/main/resources/mapper/oss/SysOssDao.xml new file mode 100644 index 0000000..bbb3af4 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/oss/SysOssDao.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysDeptDao.xml b/renren-admin/src/main/resources/mapper/sys/SysDeptDao.xml new file mode 100644 index 0000000..0941157 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysDeptDao.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysDictDataDao.xml b/renren-admin/src/main/resources/mapper/sys/SysDictDataDao.xml new file mode 100644 index 0000000..5e8e2f6 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysDictDataDao.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysDictTypeDao.xml b/renren-admin/src/main/resources/mapper/sys/SysDictTypeDao.xml new file mode 100644 index 0000000..6b92d31 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysDictTypeDao.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysMenuDao.xml b/renren-admin/src/main/resources/mapper/sys/SysMenuDao.xml new file mode 100644 index 0000000..3faeb69 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysMenuDao.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysParamsDao.xml b/renren-admin/src/main/resources/mapper/sys/SysParamsDao.xml new file mode 100644 index 0000000..964fc35 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysParamsDao.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + update sys_params set param_value = #{paramValue} where param_code = #{paramCode} + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysRoleDao.xml b/renren-admin/src/main/resources/mapper/sys/SysRoleDao.xml new file mode 100644 index 0000000..9c39f26 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysRoleDao.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysRoleDataScopeDao.xml b/renren-admin/src/main/resources/mapper/sys/SysRoleDataScopeDao.xml new file mode 100644 index 0000000..5192393 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysRoleDataScopeDao.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + delete from sys_role_data_scope where role_id in + + #{roleId} + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysRoleMenuDao.xml b/renren-admin/src/main/resources/mapper/sys/SysRoleMenuDao.xml new file mode 100644 index 0000000..912c2f2 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysRoleMenuDao.xml @@ -0,0 +1,20 @@ + + + + + + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + + delete from sys_role_menu where menu_id = #{value} + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysRoleUserDao.xml b/renren-admin/src/main/resources/mapper/sys/SysRoleUserDao.xml new file mode 100644 index 0000000..d31e2c4 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysRoleUserDao.xml @@ -0,0 +1,24 @@ + + + + + + + delete from sys_role_user where role_id in + + #{roleId} + + + + + delete from sys_role_user where user_id in + + #{userId} + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysUserDao.xml b/renren-admin/src/main/resources/mapper/sys/SysUserDao.xml new file mode 100644 index 0000000..cd2f771 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysUserDao.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + update sys_user set password = #{newPassword} where id = #{id} + + + + + + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/mapper/sys/SysUserTokenDao.xml b/renren-admin/src/main/resources/mapper/sys/SysUserTokenDao.xml new file mode 100644 index 0000000..fe77347 --- /dev/null +++ b/renren-admin/src/main/resources/mapper/sys/SysUserTokenDao.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + update sys_user_token set token = #{token} where user_id = #{userId} + + \ No newline at end of file diff --git a/renren-admin/src/main/resources/public/1.png b/renren-admin/src/main/resources/public/1.png new file mode 100644 index 0000000000000000000000000000000000000000..4c65c74764b0ca9e7ff481a1e74eb28cc5b65a32 GIT binary patch literal 299702 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�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�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 literal 0 HcmV?d00001 diff --git a/renren-admin/src/main/resources/public/favicon.ico b/renren-admin/src/main/resources/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2bd581cea17fd10bf80730efcf0563e634494a91 GIT binary patch literal 4286 zcmd6rTTc@~6vxLWUw!hKM?Z!i0Bu2TsS-6cTx^U+gVA^?F$OhFG%>~~61Dn5)V9zS zY^l%`s1Q@d(qdYKrfW;@ug1sYITNQ@=mITfcWrYzvpZ+c?>{qVXLrijKKwQ{G5Ter z2N*lZ7(0Z9r`TaMI?q4Yw%y03kaEKVvYz zHV4wmIE+Mwq08G|!|3%{xo^2#hCsp(XZ^i3KK10uu`v^8RVo!wv-R8>^!s{LW1o<^ zz!iH3q@h?Uf^+F5P`rA$!spHMXbm@+O~UIXCtUh?0a`pqca1j~x&fI&hR0bLH$23(i+)GtZ*XhYj?5!6T=)jE_JGE==8Sn93wx{U=Lka_1hZ1p5uY(i%=*PxQ5vu zA=R;*_%8AGY%vSuUr*ddeCWOub2=P(vMK)k1qW{{l=5&jczIJ>BaGdAgR9e=lSfXU z?+oYAoac%;o^wO4vvHtXa`&Z2P$uFgRFcq=T+QLgD(XmvQ`C zbl2eg`l31p_riB{=hONsaxjrifJN%iRm08DwJM)<*ztL(^}VNzPiru7={>;{cQ^cw zpp3Pbx^?mtJpTNMKOgsUz4989@$cV8?>`LNf8jjveJGZ??>~vTWe=>|{u^_yy8liy Twto=+A|O-h(XuXhX=MKaRZyEC literal 0 HcmV?d00001 diff --git a/renren-admin/src/main/resources/public/wechat.jpg b/renren-admin/src/main/resources/public/wechat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b3181ca01aad1b193d4c078d24f23a067b77cf44 GIT binary patch literal 27504 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 R9$C;tkpBPV&$vGS{{bw9N@4&2 literal 0 HcmV?d00001 diff --git a/renren-admin/src/test/java/io/renren/DynamicDataSourceTest.java b/renren-admin/src/test/java/io/renren/DynamicDataSourceTest.java new file mode 100644 index 0000000..ff77e56 --- /dev/null +++ b/renren-admin/src/test/java/io/renren/DynamicDataSourceTest.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren; + +import io.renren.service.DynamicDataSourceTestService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * 多数据源测试 + * + * @author Mark sunlightcs@gmail.com + */ +@RunWith(SpringRunner.class) +@SpringBootTest +public class DynamicDataSourceTest { + @Autowired + private DynamicDataSourceTestService dynamicDataSourceTestService; + + @Test + public void test(){ + Long id = 1067246875800000001L; + + dynamicDataSourceTestService.updateUser(id); + dynamicDataSourceTestService.updateUserBySlave1(id); + //dynamicDataSourceTestService.updateUserBySlave2(id); + } + + +} diff --git a/renren-admin/src/test/java/io/renren/RedisTest.java b/renren-admin/src/test/java/io/renren/RedisTest.java new file mode 100644 index 0000000..bc6d982 --- /dev/null +++ b/renren-admin/src/test/java/io/renren/RedisTest.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren; + +import io.renren.common.redis.RedisUtils; +import io.renren.modules.sys.entity.SysUserEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class RedisTest { + @Autowired + private RedisUtils redisUtils; + + @Test + public void contextLoads() { + SysUserEntity user = new SysUserEntity(); + user.setEmail("123456@qq.com"); + redisUtils.set("user", user); + + System.out.println(ToStringBuilder.reflectionToString(redisUtils.get("user"))); + } + +} \ No newline at end of file diff --git a/renren-admin/src/test/java/io/renren/service/DynamicDataSourceTestService.java b/renren-admin/src/test/java/io/renren/service/DynamicDataSourceTestService.java new file mode 100644 index 0000000..db29860 --- /dev/null +++ b/renren-admin/src/test/java/io/renren/service/DynamicDataSourceTestService.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.service; + +import io.renren.commons.dynamic.datasource.annotation.DataSource; +import io.renren.modules.sys.dao.SysUserDao; +import io.renren.modules.sys.entity.SysUserEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 测试多数据源 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +//@DataSource("slave1") +public class DynamicDataSourceTestService { + @Autowired + private SysUserDao sysUserDao; + + //@Transactional + public void updateUser(Long id){ + SysUserEntity user = new SysUserEntity(); + user.setId(id); + user.setMobile("13500000000"); + //sysUserDao.updateById(user); + System.out.println(sysUserDao.selectById(id)); + } + + @DataSource("slave1") + @Transactional + public void updateUserBySlave1(Long id){ + SysUserEntity user = new SysUserEntity(); + user.setId(id); + user.setMobile("13500000001"); + //sysUserDao.updateById(user); + System.out.println(sysUserDao.selectById(id)); + } + +// @DataSource("slave2") +// @Transactional +// public void updateUserBySlave2(Long id){ +// SysUserEntity user = new SysUserEntity(); +// user.setId(id); +// user.setMobile("13500000002"); +// sysUserDao.updateById(user); +// +// //测试事物 +// int i = 1/0; +// } +} \ No newline at end of file diff --git a/renren-api/Dockerfile b/renren-api/Dockerfile new file mode 100644 index 0000000..251b7fc --- /dev/null +++ b/renren-api/Dockerfile @@ -0,0 +1,7 @@ +FROM java:8 +EXPOSE 8081 + +VOLUME /tmp +ADD renren-api.jar /app.jar +RUN bash -c 'touch /app.jar' +ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/renren-api/db/dm8.sql b/renren-api/db/dm8.sql new file mode 100644 index 0000000..7f1bfd0 --- /dev/null +++ b/renren-api/db/dm8.sql @@ -0,0 +1,27 @@ +CREATE TABLE tb_user ( + id bigint NOT NULL, + username varchar(50) NOT NULL, + mobile varchar(20) NOT NULL, + password varchar(64), + create_date datetime, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX idx_user_username on tb_user(username); + +CREATE TABLE tb_token ( + id bigint NOT NULL, + user_id bigint NOT NULL, + token varchar(100) NOT NULL, + expire_date datetime, + update_date datetime, + PRIMARY KEY (id) +); + +CREATE UNIQUE INDEX idx_token_user_id on tb_token(user_id); +CREATE UNIQUE INDEX idx_token on tb_token(token); + + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (id, username, mobile, password, create_date) VALUES (1067246875800000168, 'mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', now()); + +commit; diff --git a/renren-api/db/mysql.sql b/renren-api/db/mysql.sql new file mode 100644 index 0000000..ba6f058 --- /dev/null +++ b/renren-api/db/mysql.sql @@ -0,0 +1,25 @@ +-- 用户表 +CREATE TABLE tb_user ( + id bigint NOT NULL COMMENT 'id', + username varchar(50) NOT NULL COMMENT '用户名', + mobile varchar(20) NOT NULL COMMENT '手机号', + password varchar(64) COMMENT '密码', + create_date datetime COMMENT '创建时间', + PRIMARY KEY (id), + UNIQUE INDEX (username) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户'; + +-- 用户Token表 +CREATE TABLE tb_token ( + id bigint NOT NULL COMMENT 'id', + user_id bigint NOT NULL COMMENT '用户ID', + token varchar(100) NOT NULL COMMENT 'token', + expire_date datetime COMMENT '过期时间', + update_date datetime COMMENT '更新时间', + PRIMARY KEY (id), + UNIQUE INDEX (user_id), + UNIQUE INDEX (token) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户Token'; + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (id, username, mobile, password, create_date) VALUES (1067246875900000001, 'mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', now()); diff --git a/renren-api/db/oracle.sql b/renren-api/db/oracle.sql new file mode 100644 index 0000000..69b44cb --- /dev/null +++ b/renren-api/db/oracle.sql @@ -0,0 +1,24 @@ +CREATE TABLE tb_user ( + id NUMBER(20, 0) NOT NULL, + username varchar(50) NOT NULL, + mobile varchar(20) NOT NULL, + password varchar(64), + create_date date, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX idx_user_username on tb_user(username); + +CREATE TABLE tb_token ( + id NUMBER(20, 0) NOT NULL, + user_id NUMBER(20, 0) NOT NULL, + token varchar(100) NOT NULL, + expire_date date, + update_date date, + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX idx_token_user_id on tb_token(user_id); +CREATE UNIQUE INDEX idx_token on tb_token(token); + + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (id, username, mobile, password, create_date) VALUES (1067246875900000001, 'mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', CURRENT_DATE); diff --git a/renren-api/db/postgresql.sql b/renren-api/db/postgresql.sql new file mode 100644 index 0000000..408b32c --- /dev/null +++ b/renren-api/db/postgresql.sql @@ -0,0 +1,24 @@ +CREATE TABLE tb_user ( + id int8 NOT NULL, + username varchar(50) NOT NULL, + mobile varchar(20) NOT NULL, + password varchar(64), + create_date timestamp, + PRIMARY KEY (id), + UNIQUE (username) +); + +CREATE TABLE tb_token ( + id int8 NOT NULL, + user_id int8 NOT NULL, + token varchar(100) NOT NULL, + expire_date timestamp, + update_date timestamp, + PRIMARY KEY (id), + UNIQUE (user_id), + UNIQUE (token) +); + + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (id, username, mobile, password, create_date) VALUES (1067246875900000001, 'mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', now()); diff --git a/renren-api/db/sqlserver.sql b/renren-api/db/sqlserver.sql new file mode 100644 index 0000000..3a600a4 --- /dev/null +++ b/renren-api/db/sqlserver.sql @@ -0,0 +1,24 @@ +CREATE TABLE tb_user ( + id bigint NOT NULL, + username varchar(50) NOT NULL, + mobile varchar(20) NOT NULL, + password varchar(64), + create_date datetime, + PRIMARY KEY (id), + UNIQUE (username) +); + +CREATE TABLE tb_token ( + id bigint NOT NULL, + user_id bigint NOT NULL, + token varchar(100) NOT NULL, + expire_date datetime, + update_date datetime, + PRIMARY KEY (id), + UNIQUE (user_id), + UNIQUE (token) +); + + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (id, username, mobile, password, create_date) VALUES (1067246875900000001, 'mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', getdate()); diff --git a/renren-api/pom.xml b/renren-api/pom.xml new file mode 100644 index 0000000..24fdf05 --- /dev/null +++ b/renren-api/pom.xml @@ -0,0 +1,52 @@ + + + io.renren + renren-security + 5.2.0 + + 4.0.0 + renren-api + jar + renren-api + + + + io.renren + renren-common + 5.2.0 + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + com.spotify + docker-maven-plugin + ${docker.plugin.version} + + renren/${project.artifactId} + ${project.basedir}/ + + + / + ${project.build.directory} + ${project.build.finalName}.jar + + + + + + + \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/ApiApplication.java b/renren-api/src/main/java/io/renren/ApiApplication.java new file mode 100644 index 0000000..28ec16a --- /dev/null +++ b/renren-api/src/main/java/io/renren/ApiApplication.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * renren-api + * + * @author Mark sunlightcs@gmail.com + */ +@SpringBootApplication +public class ApiApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(ApiApplication.class, args); + } + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(ApiApplication.class); + } +} diff --git a/renren-api/src/main/java/io/renren/annotation/Login.java b/renren-api/src/main/java/io/renren/annotation/Login.java new file mode 100644 index 0000000..3b9436c --- /dev/null +++ b/renren-api/src/main/java/io/renren/annotation/Login.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.annotation; + +import java.lang.annotation.*; + +/** + * 登录效验 + * @author Mark sunlightcs@gmail.com + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Login { +} diff --git a/renren-api/src/main/java/io/renren/annotation/LoginUser.java b/renren-api/src/main/java/io/renren/annotation/LoginUser.java new file mode 100644 index 0000000..7bf522a --- /dev/null +++ b/renren-api/src/main/java/io/renren/annotation/LoginUser.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 登录用户信息 + * + * @author Mark sunlightcs@gmail.com + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface LoginUser { + +} diff --git a/renren-api/src/main/java/io/renren/config/FilterConfig.java b/renren-api/src/main/java/io/renren/config/FilterConfig.java new file mode 100644 index 0000000..68bd80a --- /dev/null +++ b/renren-api/src/main/java/io/renren/config/FilterConfig.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import io.renren.common.xss.XssFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.DispatcherType; + +/** + * Filter配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class FilterConfig { + + @Bean + public FilterRegistrationBean xssFilterRegistration() { + FilterRegistrationBean registration = new FilterRegistrationBean(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new XssFilter()); + registration.addUrlPatterns("/*"); + registration.setName("xssFilter"); + return registration; + } +} diff --git a/renren-api/src/main/java/io/renren/config/MybatisPlusConfig.java b/renren-api/src/main/java/io/renren/config/MybatisPlusConfig.java new file mode 100644 index 0000000..3885f0f --- /dev/null +++ b/renren-api/src/main/java/io/renren/config/MybatisPlusConfig.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mybatis-plus配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class MybatisPlusConfig { + + /** + * 配置分页等 + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); + // 分页插件 + mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); + // 乐观锁 + mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); + // 防止全表更新与删除 + mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); + + return mybatisPlusInterceptor; + } + +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/config/SwaggerConfig.java b/renren-api/src/main/java/io/renren/config/SwaggerConfig.java new file mode 100644 index 0000000..ad41574 --- /dev/null +++ b/renren-api/src/main/java/io/renren/config/SwaggerConfig.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; + +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +@Configuration +@EnableSwagger2WebMvc +@AllArgsConstructor +public class SwaggerConfig{ + private final OpenApiExtensionResolver openApiExtensionResolver; + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + //加了ApiOperation注解的类,才生成接口文档 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + //包下的类,才生成接口文档 + //.apis(RequestHandlerSelectors.basePackage("io.renren.controller")) + .paths(PathSelectors.any()) + .build() + .extensions(openApiExtensionResolver.buildExtensions("Renren")) + .directModelSubstitute(java.util.Date.class, String.class) + .securitySchemes(security()); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("人人开源") + .description("renren-api模块接口文档") + .termsOfServiceUrl("https://www.renren.io") + .version("5.x") + .build(); + } + + private List security() { + return newArrayList( + new ApiKey("token", "token", "header") + ); + } + +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/config/WebMvcConfig.java b/renren-api/src/main/java/io/renren/config/WebMvcConfig.java new file mode 100644 index 0000000..3d06e50 --- /dev/null +++ b/renren-api/src/main/java/io/renren/config/WebMvcConfig.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.renren.common.utils.DateUtils; +import io.renren.interceptor.AuthorizationInterceptor; +import io.renren.resolver.LoginUserHandlerMethodArgumentResolver; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.ResourceHttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.TimeZone; + +/** + * MVC配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + @Autowired + private AuthorizationInterceptor authorizationInterceptor; + @Autowired + private LoginUserHandlerMethodArgumentResolver loginUserHandlerMethodArgumentResolver; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(authorizationInterceptor).addPathPatterns("/api/**"); + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(loginUserHandlerMethodArgumentResolver); + } + + @Override + public void configureMessageConverters(List> converters) { + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + converters.add(new ResourceHttpMessageConverter()); + converters.add(new AllEncompassingFormHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + converters.add(jackson2HttpMessageConverter()); + } + + @Bean + public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + ObjectMapper mapper = new ObjectMapper(); + + //日期格式转换 + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.setDateFormat(new SimpleDateFormat(DateUtils.DATE_TIME_PATTERN)); + mapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); + + //Long类型转String类型 + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(Long.class, ToStringSerializer.instance); + simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); + mapper.registerModule(simpleModule); + + converter.setObjectMapper(mapper); + return converter; + } +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/controller/ApiLoginController.java b/renren-api/src/main/java/io/renren/controller/ApiLoginController.java new file mode 100644 index 0000000..e944813 --- /dev/null +++ b/renren-api/src/main/java/io/renren/controller/ApiLoginController.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.controller; + + +import io.renren.annotation.Login; +import io.renren.common.utils.Result; +import io.renren.common.validator.ValidatorUtils; +import io.renren.dto.LoginDTO; +import io.renren.service.TokenService; +import io.renren.service.UserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.Map; + +/** + * 登录接口 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/api") +@Api(tags="登录接口") +public class ApiLoginController { + @Autowired + private UserService userService; + @Autowired + private TokenService tokenService; + + + @PostMapping("login") + @ApiOperation("登录") + public Result> login(@RequestBody LoginDTO dto){ + //表单校验 + ValidatorUtils.validateEntity(dto); + + //用户登录 + Map map = userService.login(dto); + + return new Result().ok(map); + } + + @Login + @PostMapping("logout") + @ApiOperation("退出") + public Result logout(@ApiIgnore @RequestAttribute("userId") Long userId){ + tokenService.expireToken(userId); + return new Result(); + } + +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/controller/ApiRegisterController.java b/renren-api/src/main/java/io/renren/controller/ApiRegisterController.java new file mode 100644 index 0000000..3f35d55 --- /dev/null +++ b/renren-api/src/main/java/io/renren/controller/ApiRegisterController.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.controller; + +import io.renren.common.utils.Result; +import io.renren.common.validator.ValidatorUtils; +import io.renren.dto.RegisterDTO; +import io.renren.entity.UserEntity; +import io.renren.service.UserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Date; + +/** + * 注册接口 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/api") +@Api(tags="注册接口") +public class ApiRegisterController { + @Autowired + private UserService userService; + + @PostMapping("register") + @ApiOperation("注册") + public Result register(@RequestBody RegisterDTO dto){ + //表单校验 + ValidatorUtils.validateEntity(dto); + + UserEntity user = new UserEntity(); + user.setMobile(dto.getMobile()); + user.setUsername(dto.getMobile()); + user.setPassword(DigestUtils.sha256Hex(dto.getPassword())); + user.setCreateDate(new Date()); + userService.insert(user); + + return new Result(); + } +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/controller/ApiTestController.java b/renren-api/src/main/java/io/renren/controller/ApiTestController.java new file mode 100644 index 0000000..e85f55f --- /dev/null +++ b/renren-api/src/main/java/io/renren/controller/ApiTestController.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.controller; + +import io.renren.annotation.Login; +import io.renren.annotation.LoginUser; +import io.renren.common.utils.Result; +import io.renren.entity.UserEntity; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +/** + * 测试接口 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/api") +@Api(tags="测试接口") +public class ApiTestController { + + @Login + @GetMapping("userInfo") + @ApiOperation(value="获取用户信息", response=UserEntity.class) + public Result userInfo(@ApiIgnore @LoginUser UserEntity user){ + return new Result().ok(user); + } + + @Login + @GetMapping("userId") + @ApiOperation("获取用户ID") + public Result userInfo(@ApiIgnore @RequestAttribute("userId") Long userId){ + return new Result().ok(userId); + } + + @GetMapping("notToken") + @ApiOperation("忽略Token验证测试") + public Result notToken(){ + return new Result().ok("无需token也能访问。。。"); + } + +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/dao/TokenDao.java b/renren-api/src/main/java/io/renren/dao/TokenDao.java new file mode 100644 index 0000000..65e4c66 --- /dev/null +++ b/renren-api/src/main/java/io/renren/dao/TokenDao.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.entity.TokenEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户Token + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface TokenDao extends BaseDao { + TokenEntity getByToken(String token); + + TokenEntity getByUserId(Long userId); +} diff --git a/renren-api/src/main/java/io/renren/dao/UserDao.java b/renren-api/src/main/java/io/renren/dao/UserDao.java new file mode 100644 index 0000000..babcfff --- /dev/null +++ b/renren-api/src/main/java/io/renren/dao/UserDao.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dao; + +import io.renren.common.dao.BaseDao; +import io.renren.entity.UserEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface UserDao extends BaseDao { + UserEntity getUserByMobile(String mobile); + + UserEntity getUserByUserId(Long userId); +} diff --git a/renren-api/src/main/java/io/renren/dto/LoginDTO.java b/renren-api/src/main/java/io/renren/dto/LoginDTO.java new file mode 100644 index 0000000..935bd1a --- /dev/null +++ b/renren-api/src/main/java/io/renren/dto/LoginDTO.java @@ -0,0 +1,34 @@ +/** + /** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 登录表单 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "登录表单") +public class LoginDTO { + @ApiModelProperty(value = "手机号") + @NotBlank(message="手机号不能为空") + private String mobile; + + @ApiModelProperty(value = "密码") + @NotBlank(message="密码不能为空") + private String password; + +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/dto/RegisterDTO.java b/renren-api/src/main/java/io/renren/dto/RegisterDTO.java new file mode 100644 index 0000000..ff1f45a --- /dev/null +++ b/renren-api/src/main/java/io/renren/dto/RegisterDTO.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 注册表单 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "注册表单") +public class RegisterDTO { + @ApiModelProperty(value = "手机号") + @NotBlank(message="手机号不能为空") + private String mobile; + + @ApiModelProperty(value = "密码") + @NotBlank(message="密码不能为空") + private String password; + +} diff --git a/renren-api/src/main/java/io/renren/entity/TokenEntity.java b/renren-api/src/main/java/io/renren/entity/TokenEntity.java new file mode 100644 index 0000000..4a5bd75 --- /dev/null +++ b/renren-api/src/main/java/io/renren/entity/TokenEntity.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户Token + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("tb_token") +public class TokenEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId + private Long id; + /** + * 用户ID + */ + private Long userId; + /** + * 用户token + */ + private String token; + /** + * 过期时间 + */ + private Date expireDate; + /** + * 更新时间 + */ + private Date updateDate; + +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/entity/UserEntity.java b/renren-api/src/main/java/io/renren/entity/UserEntity.java new file mode 100644 index 0000000..1934da4 --- /dev/null +++ b/renren-api/src/main/java/io/renren/entity/UserEntity.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("tb_user") +public class UserEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + @TableId + private Long id; + /** + * 用户名 + */ + private String username; + /** + * 手机号 + */ + private String mobile; + /** + * 密码 + */ + @JsonIgnore + private String password; + /** + * 创建时间 + */ + private Date createDate; + +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/exception/RenExceptionHandler.java b/renren-api/src/main/java/io/renren/exception/RenExceptionHandler.java new file mode 100644 index 0000000..9c4a968 --- /dev/null +++ b/renren-api/src/main/java/io/renren/exception/RenExceptionHandler.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.exception; + +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.common.utils.Result; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 异常处理器 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@RestControllerAdvice +public class RenExceptionHandler { + private static final Logger logger = LoggerFactory.getLogger(RenExceptionHandler.class); + + /** + * 处理自定义异常 + */ + @ExceptionHandler(RenException.class) + public Result handleRenException(RenException ex){ + Result result = new Result(); + result.error(ex.getCode(), ex.getMsg()); + + return result; + } + + @ExceptionHandler(DuplicateKeyException.class) + public Result handleDuplicateKeyException(DuplicateKeyException ex){ + Result result = new Result(); + result.error(ErrorCode.DB_RECORD_EXISTS); + + return result; + } + + @ExceptionHandler(Exception.class) + public Result handleException(Exception ex){ + logger.error(ex.getMessage(), ex); + + return new Result().error(); + } +} \ No newline at end of file diff --git a/renren-api/src/main/java/io/renren/interceptor/AuthorizationInterceptor.java b/renren-api/src/main/java/io/renren/interceptor/AuthorizationInterceptor.java new file mode 100644 index 0000000..c0bfb0e --- /dev/null +++ b/renren-api/src/main/java/io/renren/interceptor/AuthorizationInterceptor.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.interceptor; + +import io.renren.annotation.Login; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.entity.TokenEntity; +import io.renren.service.TokenService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * 权限(Token)验证 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class AuthorizationInterceptor extends HandlerInterceptorAdapter { + @Autowired + private TokenService tokenService; + + public static final String USER_KEY = "userId"; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + Login annotation; + if(handler instanceof HandlerMethod) { + annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class); + }else{ + return true; + } + + if(annotation == null){ + return true; + } + + //从header中获取token + String token = request.getHeader("token"); + //如果header中不存在token,则从参数中获取token + if(StringUtils.isBlank(token)){ + token = request.getParameter("token"); + } + + //token为空 + if(StringUtils.isBlank(token)){ + throw new RenException(ErrorCode.TOKEN_NOT_EMPTY); + } + + //查询token信息 + TokenEntity tokenEntity = tokenService.getByToken(token); + if(tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){ + throw new RenException(ErrorCode.TOKEN_INVALID); + } + + //设置userId到request里,后续根据userId,获取用户信息 + request.setAttribute(USER_KEY, tokenEntity.getUserId()); + + return true; + } +} diff --git a/renren-api/src/main/java/io/renren/resolver/LoginUserHandlerMethodArgumentResolver.java b/renren-api/src/main/java/io/renren/resolver/LoginUserHandlerMethodArgumentResolver.java new file mode 100644 index 0000000..c443ff8 --- /dev/null +++ b/renren-api/src/main/java/io/renren/resolver/LoginUserHandlerMethodArgumentResolver.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.resolver; + +import io.renren.annotation.LoginUser; +import io.renren.entity.UserEntity; +import io.renren.interceptor.AuthorizationInterceptor; +import io.renren.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +/** + * 有@LoginUser注解的方法参数,注入当前登录用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { + @Autowired + private UserService userService; + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().isAssignableFrom(UserEntity.class) && parameter.hasParameterAnnotation(LoginUser.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, + NativeWebRequest request, WebDataBinderFactory factory) throws Exception { + //获取用户ID + Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST); + if(object == null){ + return null; + } + + //获取用户信息 + UserEntity user = userService.getUserByUserId((Long)object); + + return user; + } +} diff --git a/renren-api/src/main/java/io/renren/service/TokenService.java b/renren-api/src/main/java/io/renren/service/TokenService.java new file mode 100644 index 0000000..2394400 --- /dev/null +++ b/renren-api/src/main/java/io/renren/service/TokenService.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.service; + +import io.renren.common.service.BaseService; +import io.renren.entity.TokenEntity; + +/** + * 用户Token + * + * @author Mark sunlightcs@gmail.com + */ +public interface TokenService extends BaseService { + + TokenEntity getByToken(String token); + + /** + * 生成token + * @param userId 用户ID + * @return 返回token信息 + */ + TokenEntity createToken(Long userId); + + /** + * 设置token过期 + * @param userId 用户ID + */ + void expireToken(Long userId); + +} diff --git a/renren-api/src/main/java/io/renren/service/UserService.java b/renren-api/src/main/java/io/renren/service/UserService.java new file mode 100644 index 0000000..79dcfb9 --- /dev/null +++ b/renren-api/src/main/java/io/renren/service/UserService.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.service; + +import io.renren.common.service.BaseService; +import io.renren.dto.LoginDTO; +import io.renren.entity.UserEntity; + +import java.util.Map; + +/** + * 用户 + * + * @author Mark sunlightcs@gmail.com + */ +public interface UserService extends BaseService { + + UserEntity getByMobile(String mobile); + + UserEntity getUserByUserId(Long userId); + + /** + * 用户登录 + * @param dto 登录表单 + * @return 返回登录信息 + */ + Map login(LoginDTO dto); +} diff --git a/renren-api/src/main/java/io/renren/service/impl/TokenServiceImpl.java b/renren-api/src/main/java/io/renren/service/impl/TokenServiceImpl.java new file mode 100644 index 0000000..56adb4f --- /dev/null +++ b/renren-api/src/main/java/io/renren/service/impl/TokenServiceImpl.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.service.impl; + +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.dao.TokenDao; +import io.renren.entity.TokenEntity; +import io.renren.service.TokenService; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.UUID; + + +@Service +public class TokenServiceImpl extends BaseServiceImpl implements TokenService { + /** + * 12小时后过期 + */ + private final static int EXPIRE = 3600 * 12; + + @Override + public TokenEntity getByToken(String token) { + return baseDao.getByToken(token); + } + + @Override + public TokenEntity createToken(Long userId) { + //当前时间 + Date now = new Date(); + //过期时间 + Date expireTime = new Date(now.getTime() + EXPIRE * 1000); + + //用户token + String token; + + //判断是否生成过token + TokenEntity tokenEntity = baseDao.getByUserId(userId); + if(tokenEntity == null){ + //生成一个token + token = generateToken(); + + tokenEntity = new TokenEntity(); + tokenEntity.setUserId(userId); + tokenEntity.setToken(token); + tokenEntity.setUpdateDate(now); + tokenEntity.setExpireDate(expireTime); + + //保存token + this.insert(tokenEntity); + }else{ + //判断token是否过期 + if(tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()){ + //token过期,重新生成token + token = generateToken(); + }else { + token = tokenEntity.getToken(); + } + + tokenEntity.setToken(token); + tokenEntity.setUpdateDate(now); + tokenEntity.setExpireDate(expireTime); + + //更新token + this.updateById(tokenEntity); + } + + return tokenEntity; + } + + @Override + public void expireToken(Long userId){ + Date now = new Date(); + + TokenEntity tokenEntity = new TokenEntity(); + tokenEntity.setUserId(userId); + tokenEntity.setUpdateDate(now); + tokenEntity.setExpireDate(now); + + this.updateById(tokenEntity); + } + + private String generateToken(){ + return UUID.randomUUID().toString().replace("-", ""); + } +} diff --git a/renren-api/src/main/java/io/renren/service/impl/UserServiceImpl.java b/renren-api/src/main/java/io/renren/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..fb491a4 --- /dev/null +++ b/renren-api/src/main/java/io/renren/service/impl/UserServiceImpl.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.service.impl; + +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import io.renren.common.service.impl.BaseServiceImpl; +import io.renren.common.validator.AssertUtils; +import io.renren.dao.UserDao; +import io.renren.dto.LoginDTO; +import io.renren.entity.TokenEntity; +import io.renren.entity.UserEntity; +import io.renren.service.TokenService; +import io.renren.service.UserService; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +@Service +public class UserServiceImpl extends BaseServiceImpl implements UserService { + @Autowired + private TokenService tokenService; + + @Override + public UserEntity getByMobile(String mobile) { + return baseDao.getUserByMobile(mobile); + } + + @Override + public UserEntity getUserByUserId(Long userId) { + return baseDao.getUserByUserId(userId); + } + + @Override + public Map login(LoginDTO dto) { + UserEntity user = getByMobile(dto.getMobile()); + AssertUtils.isNull(user, ErrorCode.ACCOUNT_PASSWORD_ERROR); + + //密码错误 + if(!user.getPassword().equals(DigestUtils.sha256Hex(dto.getPassword()))){ + throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR); + } + + //获取登录token + TokenEntity tokenEntity = tokenService.createToken(user.getId()); + + Map map = new HashMap<>(2); + map.put("token", tokenEntity.getToken()); + map.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis()); + + return map; + } + +} \ No newline at end of file diff --git a/renren-api/src/main/resources/application-dev.yml b/renren-api/src/main/resources/application-dev.yml new file mode 100644 index 0000000..b1bb8c9 --- /dev/null +++ b/renren-api/src/main/resources/application-dev.yml @@ -0,0 +1,33 @@ +spring: + datasource: + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/mt_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: root + password: zyx007 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 60000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + #login-username: admin + #login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true diff --git a/renren-api/src/main/resources/application-prod.yml b/renren-api/src/main/resources/application-prod.yml new file mode 100644 index 0000000..fa43e6c --- /dev/null +++ b/renren-api/src/main/resources/application-prod.yml @@ -0,0 +1,33 @@ +spring: + datasource: + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/renren_security?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: renren + password: 123456 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 60000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + #login-username: admin + #login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true diff --git a/renren-api/src/main/resources/application-test.yml b/renren-api/src/main/resources/application-test.yml new file mode 100644 index 0000000..fa43e6c --- /dev/null +++ b/renren-api/src/main/resources/application-test.yml @@ -0,0 +1,33 @@ +spring: + datasource: + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/renren_security?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: renren + password: 123456 + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 60000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + #Oracle需要打开注释 + #validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + #login-username: admin + #login-password: admin + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true diff --git a/renren-api/src/main/resources/application.yml b/renren-api/src/main/resources/application.yml new file mode 100644 index 0000000..5185f89 --- /dev/null +++ b/renren-api/src/main/resources/application.yml @@ -0,0 +1,81 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + threads: + max: 1000 + min-spare: 30 + port: 8081 + servlet: + context-path: /renren-api + session: + cookie: + http-only: true + +knife4j: + enable: true + basic: + enable: false + username: admin + password: admin + setting: + enableFooter: false + +spring: + # 环境 dev|test|prod + profiles: + active: dev + messages: + encoding: UTF-8 + basename: i18n/messages + # jackson时间格式化 + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + mvc: + pathmatch: + matching-strategy: ANT_PATH_MATCHER + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + enabled: true + redis: + database: 0 + host: 192.168.10.10 + port: 6379 + password: # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 + +renren: + redis: + open: false # 是否开启redis缓存 true开启 false关闭 + + +#mybatis +mybatis-plus: + mapper-locations: classpath*:/mapper/**/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: io.renren.entity + global-config: + #数据库相关配置 + db-config: + #主键类型 + id-type: ASSIGN_ID + banner: false + #原生配置 + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + configuration-properties: + prefix: + blobType: BLOB + boolValue: TRUE \ No newline at end of file diff --git a/renren-api/src/main/resources/banner.txt b/renren-api/src/main/resources/banner.txt new file mode 100644 index 0000000..a4028b9 --- /dev/null +++ b/renren-api/src/main/resources/banner.txt @@ -0,0 +1,5 @@ +==================================================================================================================== + + 欢迎使用 renren-api - Powered By https://www.renren.io + +==================================================================================================================== \ No newline at end of file diff --git a/renren-api/src/main/resources/logback-spring.xml b/renren-api/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..5deef21 --- /dev/null +++ b/renren-api/src/main/resources/logback-spring.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-api/src/main/resources/mapper/TokenDao.xml b/renren-api/src/main/resources/mapper/TokenDao.xml new file mode 100644 index 0000000..44665e8 --- /dev/null +++ b/renren-api/src/main/resources/mapper/TokenDao.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/renren-api/src/main/resources/mapper/UserDao.xml b/renren-api/src/main/resources/mapper/UserDao.xml new file mode 100644 index 0000000..8a1e4e9 --- /dev/null +++ b/renren-api/src/main/resources/mapper/UserDao.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/renren-common/pom.xml b/renren-common/pom.xml new file mode 100644 index 0000000..16b2586 --- /dev/null +++ b/renren-common/pom.xml @@ -0,0 +1,24 @@ + + + io.renren + renren-security + 5.2.0 + + 4.0.0 + renren-common + jar + renren-common + + + ${project.artifactId} + + + + com.alibaba + fastjson + 1.2.83 + compile + + + + \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/aspect/RedisAspect.java b/renren-common/src/main/java/io/renren/common/aspect/RedisAspect.java new file mode 100644 index 0000000..cd04001 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/aspect/RedisAspect.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.aspect; + +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * Redis切面处理类 + * + * @author Mark sunlightcs@gmail.com + */ +@Aspect +@Component +public class RedisAspect { + private Logger logger = LoggerFactory.getLogger(getClass()); + /** + * 是否开启redis缓存 true开启 false关闭 + */ + @Value("${renren.redis.open: false}") + private boolean open; + + @Around("execution(* io.renren.common.redis.RedisUtils.*(..))") + public Object around(ProceedingJoinPoint point) throws Throwable { + Object result = null; + if(open){ + try{ + result = point.proceed(); + }catch (Exception e){ + logger.error("redis error", e); + throw new RenException(ErrorCode.REDIS_ERROR); + } + } + return result; + } +} diff --git a/renren-common/src/main/java/io/renren/common/constant/Constant.java b/renren-common/src/main/java/io/renren/common/constant/Constant.java new file mode 100644 index 0000000..15a2a94 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/constant/Constant.java @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.constant; + +/** + * 常量 + * + * @author Mark sunlightcs@gmail.com + */ +public interface Constant { + /** + * 成功 + */ + int SUCCESS = 1; + /** + * 失败 + */ + int FAIL = 0; + /** + * 菜单根节点标识 + */ + Long MENU_ROOT = 0L; + /** + * 部门根节点标识 + */ + Long DEPT_ROOT = 0L; + /** + * 升序 + */ + String ASC = "asc"; + /** + * 降序 + */ + String DESC = "desc"; + /** + * 创建时间字段名 + */ + String CREATE_DATE = "create_date"; + + /** + * 数据权限过滤 + */ + String SQL_FILTER = "sqlFilter"; + /** + * 当前页码 + */ + String PAGE = "page"; + /** + * 每页显示记录数 + */ + String LIMIT = "limit"; + /** + * 排序字段 + */ + String ORDER_FIELD = "orderField"; + /** + * 排序方式 + */ + String ORDER = "order"; + /** + * token header + */ + String TOKEN_HEADER = "token"; + + /** + * 云存储配置KEY + */ + String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY"; + + /** + * 定时任务状态 + */ + enum ScheduleStatus { + /** + * 暂停 + */ + PAUSE(0), + /** + * 正常 + */ + NORMAL(1); + + private int value; + + ScheduleStatus(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + /** + * 云服务商 + */ + enum CloudService { + /** + * 七牛云 + */ + QINIU(1), + /** + * 阿里云 + */ + ALIYUN(2), + /** + * 腾讯云 + */ + QCLOUD(3); + + private int value; + + CloudService(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/convert/DateConverter.java b/renren-common/src/main/java/io/renren/common/convert/DateConverter.java new file mode 100644 index 0000000..5f9ea05 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/convert/DateConverter.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.convert; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 日期转换 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class DateConverter implements Converter { + private static final Logger logger = LoggerFactory.getLogger(DateConverter.class); + private static List formatList = new ArrayList<>(5); + static { + formatList.add("yyyy-MM"); + formatList.add("yyyy-MM-dd"); + formatList.add("yyyy-MM-dd HH:mm"); + formatList.add("yyyy-MM-dd HH:mm:ss"); + formatList.add("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + } + + @Override + public Date convert(String source) { + String value = source.trim(); + if (StringUtils.isEmpty(value)) { + return null; + } + + if(source.matches("^\\d{4}-\\d{1,2}$")){ + return parseDate(source, formatList.get(0)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){ + return parseDate(source, formatList.get(1)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){ + return parseDate(source, formatList.get(2)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){ + return parseDate(source, formatList.get(3)); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}.*T.*\\d{1,2}:\\d{1,2}:\\d{1,2}.*..*$")){ + return parseDate(source, formatList.get(4)); + } else { + throw new IllegalArgumentException("Invalid boolean value '" + source + "'"); + } + } + + /** + * 格式化日期 + * @param dateStr String 字符型日期 + * @param format String 格式 + * @return Date 日期 + */ + public Date parseDate(String dateStr, String format) { + Date date = null; + try { + DateFormat dateFormat = new SimpleDateFormat(format); + date = dateFormat.parse(dateStr); + } catch (Exception e) { + logger.error("Formatted date with date: {} and format : {} ", dateStr, format); + } + return date; + } + +} diff --git a/renren-common/src/main/java/io/renren/common/dao/BaseDao.java b/renren-common/src/main/java/io/renren/common/dao/BaseDao.java new file mode 100644 index 0000000..1c06a14 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/dao/BaseDao.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 基础Dao + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface BaseDao extends BaseMapper { + +} diff --git a/renren-common/src/main/java/io/renren/common/entity/BaseEntity.java b/renren-common/src/main/java/io/renren/common/entity/BaseEntity.java new file mode 100644 index 0000000..18d1ec8 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/entity/BaseEntity.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 基础实体类,所有实体都需要继承 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public abstract class BaseEntity implements Serializable { + /** + * id + */ + @TableId + private Long id; + /** + * 创建者 + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private Date createDate; +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/exception/ErrorCode.java b/renren-common/src/main/java/io/renren/common/exception/ErrorCode.java new file mode 100644 index 0000000..e4cf514 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/exception/ErrorCode.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.exception; + +/** + * 错误编码,由5位数字组成,前2位为模块编码,后3位为业务编码 + *

+ * 如:10001(10代表系统模块,001代表业务代码) + *

+ * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface ErrorCode { + int INTERNAL_SERVER_ERROR = 500; + int UNAUTHORIZED = 401; + + int NOT_NULL = 10001; + int DB_RECORD_EXISTS = 10002; + int PARAMS_GET_ERROR = 10003; + int ACCOUNT_PASSWORD_ERROR = 10004; + int ACCOUNT_DISABLE = 10005; + int IDENTIFIER_NOT_NULL = 10006; + int CAPTCHA_ERROR = 10007; + int SUB_MENU_EXIST = 10008; + int PASSWORD_ERROR = 10009; + int SUPERIOR_DEPT_ERROR = 10011; + int SUPERIOR_MENU_ERROR = 10012; + int DATA_SCOPE_PARAMS_ERROR = 10013; + int DEPT_SUB_DELETE_ERROR = 10014; + int DEPT_USER_DELETE_ERROR = 10015; + int UPLOAD_FILE_EMPTY = 10019; + int TOKEN_NOT_EMPTY = 10020; + int TOKEN_INVALID = 10021; + int ACCOUNT_LOCK = 10022; + int OSS_UPLOAD_FILE_ERROR = 10024; + int REDIS_ERROR = 10027; + int JOB_ERROR = 10028; + int INVALID_SYMBOL = 10029; +} diff --git a/renren-common/src/main/java/io/renren/common/exception/ExceptionUtils.java b/renren-common/src/main/java/io/renren/common/exception/ExceptionUtils.java new file mode 100644 index 0000000..ce79649 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/exception/ExceptionUtils.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.exception; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * Exception工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ExceptionUtils { + + /** + * 获取异常信息 + * @param ex 异常 + * @return 返回异常信息 + */ + public static String getErrorStackTrace(Exception ex){ + StringWriter sw = null; + PrintWriter pw = null; + try { + sw = new StringWriter(); + pw = new PrintWriter(sw, true); + ex.printStackTrace(pw); + }finally { + try { + if(pw != null) { + pw.close(); + } + } catch (Exception e) { + + } + try { + if(sw != null) { + sw.close(); + } + } catch (IOException e) { + + } + } + + return sw.toString(); + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/exception/RenException.java b/renren-common/src/main/java/io/renren/common/exception/RenException.java new file mode 100644 index 0000000..baf0825 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/exception/RenException.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.exception; + + +import io.renren.common.utils.MessageUtils; + +/** + * 自定义异常 + * + * @author Mark sunlightcs@gmail.com + */ +public class RenException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private int code; + private String msg; + + public RenException(int code) { + this.code = code; + this.msg = MessageUtils.getMessage(code); + } + + public RenException(int code, String... params) { + this.code = code; + this.msg = MessageUtils.getMessage(code, params); + } + + public RenException(int code, Throwable e) { + super(e); + this.code = code; + this.msg = MessageUtils.getMessage(code); + } + + public RenException(int code, Throwable e, String... params) { + super(e); + this.code = code; + this.msg = MessageUtils.getMessage(code, params); + } + + public RenException(String msg) { + super(msg); + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + } + + public RenException(String msg, Throwable e) { + super(msg, e); + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/page/PageData.java b/renren-common/src/main/java/io/renren/common/page/PageData.java new file mode 100644 index 0000000..c8dd3ce --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/page/PageData.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.page; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@ApiModel(value = "分页数据") +public class PageData implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "总记录数") + private int total; + + @ApiModelProperty(value = "列表数据") + private List list; + + /** + * 分页 + * @param list 列表数据 + * @param total 总记录数 + */ + public PageData(List list, long total) { + this.list = list; + this.total = (int)total; + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/redis/RedisConfig.java b/renren-common/src/main/java/io/renren/common/redis/RedisConfig.java new file mode 100644 index 0000000..f3ccd5f --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/redis/RedisConfig.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.redis; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import org.springframework.cache.CacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.*; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * Redis配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class RedisConfig { + @Resource + private RedisConnectionFactory factory; + + @Bean + public Jackson2JsonRedisSerializer jackson2JsonRedisSerializer(){ + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(objectMapper); + + return jackson2JsonRedisSerializer; + } + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(jackson2JsonRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer()); + redisTemplate.setConnectionFactory(factory); + + return redisTemplate; + } + + @Bean + public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { + RedisSerializer redisSerializer = new StringRedisSerializer(); + + ObjectMapper om = new ObjectMapper(); + // 解决jackson2无法反序列化LocalDateTime的问题 + //LocalDatetime序列化 + JavaTimeModule timeModule = new JavaTimeModule(); + timeModule.addDeserializer(LocalDate.class, + new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + timeModule.addDeserializer(LocalDateTime.class, + new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + timeModule.addSerializer(LocalDate.class, + new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + timeModule.addSerializer(LocalDateTime.class, + new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + om.registerModule(timeModule); + + //设置GenericJackson2JsonRedisSerializer可以将R类的对象类型也能进行JSON保存 + om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); + GenericJackson2JsonRedisSerializer gen = new GenericJackson2JsonRedisSerializer(om); + + //配置序列化 + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); + RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(gen)); + return RedisCacheManager + .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)) + .cacheDefaults(redisCacheConfiguration).build(); + } + +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/redis/RedisKeys.java b/renren-common/src/main/java/io/renren/common/redis/RedisKeys.java new file mode 100644 index 0000000..dbcdb6c --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/redis/RedisKeys.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.redis; + +/** + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class RedisKeys { + /** + * 系统参数Key + */ + public static String getSysParamsKey(){ + return "sys:params"; + } + + /** + * 验证码Key + */ + public static String getCaptchaKey(String uuid){ + return "sys:captcha:" + uuid; + } + + /** + * 登录用户Key + */ + public static String getSecurityUserKey(Long id){ + return "sys:security:user:" + id; + } + + /** + * 系统日志Key + */ + public static String getSysLogKey(){ + return "sys:log"; + } + + /** + * 系统资源Key + */ + public static String getSysResourceKey(){ + return "sys:resource"; + } + + /** + * 用户菜单导航Key + */ + public static String getUserMenuNavKey(Long userId){ + return "sys:user:nav:" + userId; + } + + /** + * 用户权限标识Key + */ + public static String getUserPermissionsKey(Long userId){ + return "sys:user:permissions:" + userId; + } +} diff --git a/renren-common/src/main/java/io/renren/common/redis/RedisUtils.java b/renren-common/src/main/java/io/renren/common/redis/RedisUtils.java new file mode 100644 index 0000000..28ad234 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/redis/RedisUtils.java @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.redis; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * Redis工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class RedisUtils { + @Autowired + private RedisTemplate redisTemplate; + + /** 默认过期时长为24小时,单位:秒 */ + public final static long DEFAULT_EXPIRE = 60 * 60 * 24L; + /** 过期时长为1小时,单位:秒 */ + public final static long HOUR_ONE_EXPIRE = 60 * 60 * 1L; + /** 过期时长为6小时,单位:秒 */ + public final static long HOUR_SIX_EXPIRE = 60 * 60 * 6L; + /** 不设置过期时长 */ + public final static long NOT_EXPIRE = -1L; + + public void set(String key, Object value, long expire){ + redisTemplate.opsForValue().set(key, value); + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + + public void set(String key, Object value){ + set(key, value, DEFAULT_EXPIRE); + } + + public Object get(String key, long expire) { + Object value = redisTemplate.opsForValue().get(key); + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + return value; + } + + public Object get(String key) { + return get(key, NOT_EXPIRE); + } + + public void delete(String key) { + redisTemplate.delete(key); + } + + public void delete(Collection keys) { + redisTemplate.delete(keys); + } + + public Object hGet(String key, String field) { + return redisTemplate.opsForHash().get(key, field); + } + + public Map hGetAll(String key){ + HashOperations hashOperations = redisTemplate.opsForHash(); + return hashOperations.entries(key); + } + + public void hMSet(String key, Map map){ + hMSet(key, map, DEFAULT_EXPIRE); + } + + public void hMSet(String key, Map map, long expire){ + redisTemplate.opsForHash().putAll(key, map); + + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + + public void hSet(String key, String field, Object value) { + hSet(key, field, value, DEFAULT_EXPIRE); + } + + public void hSet(String key, String field, Object value, long expire) { + redisTemplate.opsForHash().put(key, field, value); + + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + + public void expire(String key, long expire){ + redisTemplate.expire(key, expire, TimeUnit.SECONDS); + } + + public void hDel(String key, Object... fields){ + redisTemplate.opsForHash().delete(key, fields); + } + + public void leftPush(String key, Object value){ + leftPush(key, value, DEFAULT_EXPIRE); + } + + public void leftPush(String key, Object value, long expire){ + redisTemplate.opsForList().leftPush(key, value); + + if(expire != NOT_EXPIRE){ + expire(key, expire); + } + } + + public Object rightPop(String key){ + return redisTemplate.opsForList().rightPop(key); + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/service/BaseService.java b/renren-common/src/main/java/io/renren/common/service/BaseService.java new file mode 100644 index 0000000..6de9f9c --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/service/BaseService.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.service; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; + +import java.io.Serializable; +import java.util.Collection; + +/** + * 基础服务接口,所有Service接口都要继承 + * + * @author Mark sunlightcs@gmail.com + */ +public interface BaseService { + Class currentModelClass(); + + /** + *

+ * 插入一条记录(选择字段,策略插入) + *

+ * + * @param entity 实体对象 + */ + boolean insert(T entity); + + /** + *

+ * 插入(批量),该方法不支持 Oracle、SQL Server + *

+ * + * @param entityList 实体对象集合 + */ + boolean insertBatch(Collection entityList); + + /** + *

+ * 插入(批量),该方法不支持 Oracle、SQL Server + *

+ * + * @param entityList 实体对象集合 + * @param batchSize 插入批次数量 + */ + boolean insertBatch(Collection entityList, int batchSize); + + /** + *

+ * 根据 ID 选择修改 + *

+ * + * @param entity 实体对象 + */ + boolean updateById(T entity); + + /** + *

+ * 根据 whereEntity 条件,更新记录 + *

+ * + * @param entity 实体对象 + * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} + */ + boolean update(T entity, Wrapper updateWrapper); + + /** + *

+ * 根据ID 批量更新 + *

+ * + * @param entityList 实体对象集合 + */ + boolean updateBatchById(Collection entityList); + + /** + *

+ * 根据ID 批量更新 + *

+ * + * @param entityList 实体对象集合 + * @param batchSize 更新批次数量 + */ + boolean updateBatchById(Collection entityList, int batchSize); + + /** + *

+ * 根据 ID 查询 + *

+ * + * @param id 主键ID + */ + T selectById(Serializable id); + + /** + *

+ * 根据 ID 删除 + *

+ * + * @param id 主键ID + */ + boolean deleteById(Serializable id); + + /** + *

+ * 删除(根据ID 批量删除) + *

+ * + * @param idList 主键ID列表 + */ + boolean deleteBatchIds(Collection idList); +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/service/CrudService.java b/renren-common/src/main/java/io/renren/common/service/CrudService.java new file mode 100644 index 0000000..78e636c --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/service/CrudService.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package io.renren.common.service; + +import io.renren.common.page.PageData; + +import java.util.List; +import java.util.Map; + +/** + * CRUD基础服务接口 + * + * @author Mark sunlightcs@gmail.com + */ +public interface CrudService extends BaseService { + + PageData page(Map params); + + List list(Map params); + + D get(Long id); + + void save(D dto); + + void update(D dto); + + void delete(Long[] ids); + +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/service/impl/BaseServiceImpl.java b/renren-common/src/main/java/io/renren/common/service/impl/BaseServiceImpl.java new file mode 100644 index 0000000..adfcedd --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/service/impl/BaseServiceImpl.java @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.enums.SqlMethod; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import io.renren.common.constant.Constant; +import io.renren.common.page.PageData; +import io.renren.common.service.BaseService; +import io.renren.common.utils.ConvertUtils; +import org.apache.ibatis.binding.MapperMethod; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; +import org.apache.ibatis.session.SqlSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; + +/** + * 基础服务类,所有Service都要继承 + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class BaseServiceImpl, T> implements BaseService { + @Autowired + protected M baseDao; + protected Log log = LogFactory.getLog(getClass()); + + /** + * 获取分页对象 + * @param params 分页查询参数 + * @param defaultOrderField 默认排序字段 + * @param isAsc 排序方式 + */ + protected IPage getPage(Map params, String defaultOrderField, boolean isAsc) { + //分页参数 + long curPage = 1; + long limit = 10; + + if(params.get(Constant.PAGE) != null){ + curPage = Long.parseLong((String)params.get(Constant.PAGE)); + } + if(params.get(Constant.LIMIT) != null){ + limit = Long.parseLong((String)params.get(Constant.LIMIT)); + } + + //分页对象 + Page page = new Page<>(curPage, limit); + + //分页参数 + params.put(Constant.PAGE, page); + + //排序字段 + String orderField = (String)params.get(Constant.ORDER_FIELD); + String order = (String)params.get(Constant.ORDER); + + //前端字段排序 + if(StringUtils.isNotBlank(orderField) && StringUtils.isNotBlank(order)){ + if(Constant.ASC.equalsIgnoreCase(order)) { + return page.addOrder(OrderItem.asc(orderField)); + }else { + return page.addOrder(OrderItem.desc(orderField)); + } + } + + //没有排序字段,则不排序 + if(StringUtils.isBlank(defaultOrderField)){ + return page; + } + + //默认排序 + if(isAsc) { + page.addOrder(OrderItem.asc(defaultOrderField)); + }else { + page.addOrder(OrderItem.desc(defaultOrderField)); + } + + return page; + } + + protected PageData getPageData(List list, long total, Class target){ + List targetList = ConvertUtils.sourceToTarget(list, target); + + return new PageData<>(targetList, total); + } + + protected PageData getPageData(IPage page, Class target){ + return getPageData(page.getRecords(), page.getTotal(), target); + } + + protected void paramsToLike(Map params, String... likes){ + for (String like : likes){ + String val = (String)params.get(like); + if (StringUtils.isNotBlank(val)){ + params.put(like, "%" + val + "%"); + }else { + params.put(like, null); + } + } + } + + /** + *

+ * 判断数据库操作是否成功 + *

+ *

+ * 注意!! 该方法为 Integer 判断,不可传入 int 基本类型 + *

+ * + * @param result 数据库操作返回影响条数 + * @return boolean + */ + protected static boolean retBool(Integer result) { + return SqlHelper.retBool(result); + } + + protected Class currentMapperClass() { + return (Class) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 0); + } + + @Override + public Class currentModelClass() { + return (Class)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 1); + } + + protected String getSqlStatement(SqlMethod sqlMethod) { + return SqlHelper.getSqlStatement(this.currentMapperClass(), sqlMethod); + } + + @Override + public boolean insert(T entity) { + return BaseServiceImpl.retBool(baseDao.insert(entity)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean insertBatch(Collection entityList) { + return insertBatch(entityList, 100); + } + + /** + * 批量插入 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean insertBatch(Collection entityList, int batchSize) { + String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE); + return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity)); + } + + /** + * 执行批量操作 + */ + protected boolean executeBatch(Collection list, int batchSize, BiConsumer consumer) { + return SqlHelper.executeBatch(this.currentModelClass(), this.log, list, batchSize, consumer); + } + + + @Override + public boolean updateById(T entity) { + return BaseServiceImpl.retBool(baseDao.updateById(entity)); + } + + @Override + public boolean update(T entity, Wrapper updateWrapper) { + return BaseServiceImpl.retBool(baseDao.update(entity, updateWrapper)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateBatchById(Collection entityList) { + return updateBatchById(entityList, 30); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateBatchById(Collection entityList, int batchSize) { + String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID); + return executeBatch(entityList, batchSize, (sqlSession, entity) -> { + MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); + param.put(Constants.ENTITY, entity); + sqlSession.update(sqlStatement, param); + }); + } + + @Override + public T selectById(Serializable id) { + return baseDao.selectById(id); + } + + @Override + public boolean deleteById(Serializable id) { + return SqlHelper.retBool(baseDao.deleteById(id)); + } + + @Override + public boolean deleteBatchIds(Collection idList) { + return SqlHelper.retBool(baseDao.deleteBatchIds(idList)); + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/service/impl/CrudServiceImpl.java b/renren-common/src/main/java/io/renren/common/service/impl/CrudServiceImpl.java new file mode 100644 index 0000000..dc12fca --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/service/impl/CrudServiceImpl.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + *

+ * https://www.renren.io + *

+ * 版权所有,侵权必究! + */ + +package io.renren.common.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; +import io.renren.common.page.PageData; +import io.renren.common.service.CrudService; +import io.renren.common.utils.ConvertUtils; +import org.springframework.beans.BeanUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * CRUD基础服务类 + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class CrudServiceImpl, T, D> extends BaseServiceImpl implements CrudService { + + protected Class currentDtoClass() { + return (Class)ReflectionKit.getSuperClassGenericType(getClass(), CrudServiceImpl.class, 2); + } + + @Override + public PageData page(Map params) { + IPage page = baseDao.selectPage( + getPage(params, null, false), + getWrapper(params) + ); + + return getPageData(page, currentDtoClass()); + } + + @Override + public List list(Map params) { + List entityList = baseDao.selectList(getWrapper(params)); + + return ConvertUtils.sourceToTarget(entityList, currentDtoClass()); + } + + public abstract QueryWrapper getWrapper(Map params); + + @Override + public D get(Long id) { + T entity = baseDao.selectById(id); + + return ConvertUtils.sourceToTarget(entity, currentDtoClass()); + } + + @Override + public void save(D dto) { + T entity = ConvertUtils.sourceToTarget(dto, currentModelClass()); + insert(entity); + + //copy主键值到dto + BeanUtils.copyProperties(entity, dto); + } + + @Override + public void update(D dto) { + T entity = ConvertUtils.sourceToTarget(dto, currentModelClass()); + updateById(entity); + } + + @Override + public void delete(Long[] ids) { + baseDao.deleteBatchIds(Arrays.asList(ids)); + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/utils/ConvertUtils.java b/renren-common/src/main/java/io/renren/common/utils/ConvertUtils.java new file mode 100644 index 0000000..f5c7680 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/ConvertUtils.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * 转换工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ConvertUtils { + private static Logger logger = LoggerFactory.getLogger(ConvertUtils.class); + + public static T sourceToTarget(Object source, Class target){ + if(source == null){ + return null; + } + T targetObject = null; + try { + targetObject = target.newInstance(); + BeanUtils.copyProperties(source, targetObject); + } catch (Exception e) { + logger.error("convert error ", e); + } + + return targetObject; + } + + public static List sourceToTarget(Collection sourceList, Class target){ + if(sourceList == null){ + return null; + } + + List targetList = new ArrayList<>(sourceList.size()); + try { + for(Object source : sourceList){ + T targetObject = target.newInstance(); + BeanUtils.copyProperties(source, targetObject); + targetList.add(targetObject); + } + }catch (Exception e){ + logger.error("convert error ", e); + } + + return targetList; + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/utils/DateUtils.java b/renren-common/src/main/java/io/renren/common/utils/DateUtils.java new file mode 100644 index 0000000..e7d8a37 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/DateUtils.java @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 日期处理 + * + * @author Mark sunlightcs@gmail.com + */ +public class DateUtils { + /** 时间格式(yyyy-MM-dd) */ + public final static String DATE_PATTERN = "yyyy-MM-dd"; + /** 时间格式(yyyy-MM-dd HH:mm:ss) */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + /** + * 日期格式化 日期格式为:yyyy-MM-dd + * @param date 日期 + * @return 返回yyyy-MM-dd格式日期 + */ + public static String format(Date date) { + return format(date, DATE_PATTERN); + } + + /** + * 日期格式化 日期格式为:yyyy-MM-dd + * @param date 日期 + * @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN + * @return 返回yyyy-MM-dd格式日期 + */ + public static String format(Date date, String pattern) { + if(date != null){ + SimpleDateFormat df = new SimpleDateFormat(pattern); + return df.format(date); + } + return null; + } + + /** + * 日期解析 + * @param date 日期 + * @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN + * @return 返回Date + */ + public static Date parse(String date, String pattern) { + try { + return new SimpleDateFormat(pattern).parse(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 字符串转换成日期 + * @param strDate 日期字符串 + * @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN + */ + public static Date stringToDate(String strDate, String pattern) { + if (StringUtils.isBlank(strDate)){ + return null; + } + + DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); + return fmt.parseLocalDateTime(strDate).toDate(); + } + + /** + * 根据周数,获取开始日期、结束日期 + * @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周 + * @return 返回date[0]开始日期、date[1]结束日期 + */ + public static Date[] getWeekStartAndEnd(int week) { + DateTime dateTime = new DateTime(); + LocalDate date = new LocalDate(dateTime.plusWeeks(week)); + + date = date.dayOfWeek().withMinimumValue(); + Date beginDate = date.toDate(); + Date endDate = date.plusDays(6).toDate(); + return new Date[]{beginDate, endDate}; + } + + /** + * 对日期的【秒】进行加/减 + * + * @param date 日期 + * @param seconds 秒数,负数为减 + * @return 加/减几秒后的日期 + */ + public static Date addDateSeconds(Date date, int seconds) { + DateTime dateTime = new DateTime(date); + return dateTime.plusSeconds(seconds).toDate(); + } + + /** + * 对日期的【分钟】进行加/减 + * + * @param date 日期 + * @param minutes 分钟数,负数为减 + * @return 加/减几分钟后的日期 + */ + public static Date addDateMinutes(Date date, int minutes) { + DateTime dateTime = new DateTime(date); + return dateTime.plusMinutes(minutes).toDate(); + } + + /** + * 对日期的【小时】进行加/减 + * + * @param date 日期 + * @param hours 小时数,负数为减 + * @return 加/减几小时后的日期 + */ + public static Date addDateHours(Date date, int hours) { + DateTime dateTime = new DateTime(date); + return dateTime.plusHours(hours).toDate(); + } + + /** + * 对日期的【天】进行加/减 + * + * @param date 日期 + * @param days 天数,负数为减 + * @return 加/减几天后的日期 + */ + public static Date addDateDays(Date date, int days) { + DateTime dateTime = new DateTime(date); + return dateTime.plusDays(days).toDate(); + } + + /** + * 对日期的【周】进行加/减 + * + * @param date 日期 + * @param weeks 周数,负数为减 + * @return 加/减几周后的日期 + */ + public static Date addDateWeeks(Date date, int weeks) { + DateTime dateTime = new DateTime(date); + return dateTime.plusWeeks(weeks).toDate(); + } + + /** + * 对日期的【月】进行加/减 + * + * @param date 日期 + * @param months 月数,负数为减 + * @return 加/减几月后的日期 + */ + public static Date addDateMonths(Date date, int months) { + DateTime dateTime = new DateTime(date); + return dateTime.plusMonths(months).toDate(); + } + + /** + * 对日期的【年】进行加/减 + * + * @param date 日期 + * @param years 年数,负数为减 + * @return 加/减几年后的日期 + */ + public static Date addDateYears(Date date, int years) { + DateTime dateTime = new DateTime(date); + return dateTime.plusYears(years).toDate(); + } +} diff --git a/renren-common/src/main/java/io/renren/common/utils/HttpContextUtils.java b/renren-common/src/main/java/io/renren/common/utils/HttpContextUtils.java new file mode 100644 index 0000000..5eb78dd --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/HttpContextUtils.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * Http + * + * @author Mark sunlightcs@gmail.com + */ +public class HttpContextUtils { + + public static HttpServletRequest getHttpServletRequest() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if(requestAttributes == null){ + return null; + } + + return ((ServletRequestAttributes) requestAttributes).getRequest(); + } + + public static Map getParameterMap(HttpServletRequest request) { + Enumeration parameters = request.getParameterNames(); + + Map params = new HashMap<>(); + while (parameters.hasMoreElements()) { + String parameter = parameters.nextElement(); + String value = request.getParameter(parameter); + if (StringUtils.isNotBlank(value)) { + params.put(parameter, value); + } + } + + return params; + } + + public static String getDomain(){ + HttpServletRequest request = getHttpServletRequest(); + StringBuffer url = request.getRequestURL(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString(); + } + + public static String getOrigin(){ + HttpServletRequest request = getHttpServletRequest(); + return request.getHeader(HttpHeaders.ORIGIN); + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/utils/IpUtils.java b/renren-common/src/main/java/io/renren/common/utils/IpUtils.java new file mode 100644 index 0000000..933879d --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/IpUtils.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; + +/** + * IP地址 + * + * @author Mark sunlightcs@gmail.com + */ +public class IpUtils { + private static Logger logger = LoggerFactory.getLogger(IpUtils.class); + + /** + * 获取IP地址 + * + * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 + * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + String unknown = "unknown"; + String ip = null; + try { + ip = request.getHeader("x-forwarded-for"); + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } catch (Exception e) { + logger.error("IPUtils ERROR ", e); + } + + return ip; + } + +} diff --git a/renren-common/src/main/java/io/renren/common/utils/JsonUtils.java b/renren-common/src/main/java/io/renren/common/utils/JsonUtils.java new file mode 100644 index 0000000..984b033 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/JsonUtils.java @@ -0,0 +1,68 @@ +package io.renren.common.utils; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.ArrayList; +import java.util.List; + +/** + * JSON 工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class JsonUtils { + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static String toJsonString(Object object) { + try { + return objectMapper.writeValueAsString(object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(String text, Class clazz) { + if (StrUtil.isEmpty(text)) { + return null; + } + try { + return objectMapper.readValue(text, clazz); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(byte[] bytes, Class clazz) { + if (ArrayUtil.isEmpty(bytes)) { + return null; + } + try { + return objectMapper.readValue(bytes, clazz); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static T parseObject(String text, TypeReference typeReference) { + try { + return objectMapper.readValue(text, typeReference); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static List parseArray(String text, Class clazz) { + if (StrUtil.isEmpty(text)) { + return new ArrayList<>(); + } + try { + return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/renren-common/src/main/java/io/renren/common/utils/MessageUtils.java b/renren-common/src/main/java/io/renren/common/utils/MessageUtils.java new file mode 100644 index 0000000..ae28366 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/MessageUtils.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; + +/** + * 国际化 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class MessageUtils { + private static MessageSource messageSource; + static { + messageSource = (MessageSource)SpringContextUtils.getBean("messageSource"); + } + + public static String getMessage(int code){ + return getMessage(code, new String[0]); + } + + public static String getMessage(int code, String... params){ + return messageSource.getMessage(code+"", params, LocaleContextHolder.getLocale()); + } +} diff --git a/renren-common/src/main/java/io/renren/common/utils/Result.java b/renren-common/src/main/java/io/renren/common/utils/Result.java new file mode 100644 index 0000000..801d183 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/Result.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import io.renren.common.exception.ErrorCode; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +/** + * 响应数据 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ApiModel(value = "响应") +public class Result implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 编码:0表示成功,其他值表示失败 + */ + @ApiModelProperty(value = "编码:0表示成功,其他值表示失败") + private int code = 0; + /** + * 消息内容 + */ + @ApiModelProperty(value = "消息内容") + private String msg = "success"; + /** + * 响应数据 + */ + @ApiModelProperty(value = "响应数据") + private T data; + + public Result ok(T data) { + this.setData(data); + return this; + } + + public boolean success(){ + return code == 0; + } + + public Result error() { + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = MessageUtils.getMessage(this.code); + return this; + } + + public Result error(int code) { + this.code = code; + this.msg = MessageUtils.getMessage(this.code); + return this; + } + + public Result error(int code, String msg) { + this.code = code; + this.msg = msg; + return this; + } + + public Result error(String msg) { + this.code = ErrorCode.INTERNAL_SERVER_ERROR; + this.msg = msg; + return this; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } +} diff --git a/renren-common/src/main/java/io/renren/common/utils/SpringContextUtils.java b/renren-common/src/main/java/io/renren/common/utils/SpringContextUtils.java new file mode 100644 index 0000000..4e3c1f4 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/SpringContextUtils.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * Spring Context 工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class SpringContextUtils implements ApplicationContextAware { + public static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + SpringContextUtils.applicationContext = applicationContext; + } + + public static Object getBean(String name) { + return applicationContext.getBean(name); + } + + public static T getBean(Class requiredType) { + return applicationContext.getBean(requiredType); + } + + public static T getBean(String name, Class requiredType) { + return applicationContext.getBean(name, requiredType); + } + + public static boolean containsBean(String name) { + return applicationContext.containsBean(name); + } + + public static boolean isSingleton(String name) { + return applicationContext.isSingleton(name); + } + + public static Class getType(String name) { + return applicationContext.getType(name); + } + +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/utils/TreeNode.java b/renren-common/src/main/java/io/renren/common/utils/TreeNode.java new file mode 100644 index 0000000..fb49d14 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/TreeNode.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import lombok.Data; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 树节点,所有需要实现树节点的,都需要继承该类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ + @Data +public class TreeNode implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 主键 + */ + private Long id; + /** + * 上级ID + */ + private Long pid; + /** + * 子节点列表 + */ + private List children = new ArrayList<>(); +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/utils/TreeUtils.java b/renren-common/src/main/java/io/renren/common/utils/TreeUtils.java new file mode 100644 index 0000000..e986e66 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/utils/TreeUtils.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import io.renren.common.validator.AssertUtils; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * 树形结构工具类,如:菜单、部门等 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class TreeUtils { + + /** + * 根据pid,构建树节点 + */ + public static List build(List treeNodes, Long pid) { + //pid不能为空 + AssertUtils.isNull(pid, "pid"); + + List treeList = new ArrayList<>(); + for(T treeNode : treeNodes) { + if (pid.equals(treeNode.getPid())) { + treeList.add(findChildren(treeNodes, treeNode)); + } + } + + return treeList; + } + + /** + * 查找子节点 + */ + private static T findChildren(List treeNodes, T rootNode) { + for(T treeNode : treeNodes) { + if(rootNode.getId().equals(treeNode.getPid())) { + rootNode.getChildren().add(findChildren(treeNodes, treeNode)); + } + } + return rootNode; + } + + /** + * 构建树节点 + */ + public static List build(List treeNodes) { + List result = new ArrayList<>(); + + //list转map + Map nodeMap = new LinkedHashMap<>(treeNodes.size()); + for(T treeNode : treeNodes){ + nodeMap.put(treeNode.getId(), treeNode); + } + + for(T node : nodeMap.values()) { + T parent = nodeMap.get(node.getPid()); + if(parent != null && !(node.getId().equals(parent.getId()))){ + parent.getChildren().add(node); + continue; + } + + result.add(node); + } + + return result; + } + +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/validator/AssertUtils.java b/renren-common/src/main/java/io/renren/common/validator/AssertUtils.java new file mode 100644 index 0000000..09a28c5 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/validator/AssertUtils.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ArrayUtil; +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * 校验工具类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class AssertUtils { + + public static void isBlank(String str, String... params) { + isBlank(str, ErrorCode.NOT_NULL, params); + } + + public static void isBlank(String str, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if (StringUtils.isBlank(str)) { + throw new RenException(code, params); + } + } + + public static void isNull(Object object, String... params) { + isNull(object, ErrorCode.NOT_NULL, params); + } + + public static void isNull(Object object, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if (object == null) { + throw new RenException(code, params); + } + } + + public static void isArrayEmpty(Object[] array, String... params) { + isArrayEmpty(array, ErrorCode.NOT_NULL, params); + } + + public static void isArrayEmpty(Object[] array, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if(ArrayUtil.isEmpty(array)){ + throw new RenException(code, params); + } + } + + public static void isListEmpty(List list, String... params) { + isListEmpty(list, ErrorCode.NOT_NULL, params); + } + + public static void isListEmpty(List list, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if(CollUtil.isEmpty(list)){ + throw new RenException(code, params); + } + } + + public static void isMapEmpty(Map map, String... params) { + isMapEmpty(map, ErrorCode.NOT_NULL, params); + } + + public static void isMapEmpty(Map map, Integer code, String... params) { + if(code == null){ + throw new RenException(ErrorCode.NOT_NULL, "code"); + } + + if(MapUtil.isEmpty(map)){ + throw new RenException(code, params); + } + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/validator/ValidatorUtils.java b/renren-common/src/main/java/io/renren/common/validator/ValidatorUtils.java new file mode 100644 index 0000000..61a02f7 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/validator/ValidatorUtils.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator; + +import io.renren.common.exception.RenException; +import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Locale; +import java.util.Set; + +/** + * hibernate-validator校验工具类 + * 参考文档:http://docs.jboss.org/hibernate/validator/6.0/reference/en-US/html_single/ + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class ValidatorUtils { + + private static ResourceBundleMessageSource getMessageSource() { + ResourceBundleMessageSource bundleMessageSource = new ResourceBundleMessageSource(); + bundleMessageSource.setDefaultEncoding("UTF-8"); + bundleMessageSource.setBasenames("i18n/validation"); + return bundleMessageSource; + } + + /** + * 校验对象 + * @param object 待校验对象 + * @param groups 待校验的组 + */ + public static void validateEntity(Object object, Class... groups) + throws RenException { + Locale.setDefault(LocaleContextHolder.getLocale()); + Validator validator = Validation.byDefaultProvider().configure().messageInterpolator( + new ResourceBundleMessageInterpolator(new MessageSourceResourceBundleLocator(getMessageSource()))) + .buildValidatorFactory().getValidator(); + + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) { + ConstraintViolation constraint = constraintViolations.iterator().next(); + throw new RenException(constraint.getMessage()); + } + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/validator/group/AddGroup.java b/renren-common/src/main/java/io/renren/common/validator/group/AddGroup.java new file mode 100644 index 0000000..9a8cfb9 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/validator/group/AddGroup.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 新增 Group + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface AddGroup { + +} diff --git a/renren-common/src/main/java/io/renren/common/validator/group/DefaultGroup.java b/renren-common/src/main/java/io/renren/common/validator/group/DefaultGroup.java new file mode 100644 index 0000000..2e69248 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/validator/group/DefaultGroup.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 默认 Group + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface DefaultGroup { + +} diff --git a/renren-common/src/main/java/io/renren/common/validator/group/Group.java b/renren-common/src/main/java/io/renren/common/validator/group/Group.java new file mode 100644 index 0000000..23b2328 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/validator/group/Group.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +import javax.validation.GroupSequence; + +/** + * 定义校验顺序,如果AddGroup组失败,则UpdateGroup组不会再校验 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@GroupSequence({AddGroup.class, UpdateGroup.class}) +public interface Group { + +} diff --git a/renren-common/src/main/java/io/renren/common/validator/group/UpdateGroup.java b/renren-common/src/main/java/io/renren/common/validator/group/UpdateGroup.java new file mode 100644 index 0000000..83ed02c --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/validator/group/UpdateGroup.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 修改 Group + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public interface UpdateGroup { + +} diff --git a/renren-common/src/main/java/io/renren/common/xss/SqlFilter.java b/renren-common/src/main/java/io/renren/common/xss/SqlFilter.java new file mode 100644 index 0000000..9cf2494 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/xss/SqlFilter.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.xss; + +import io.renren.common.exception.ErrorCode; +import io.renren.common.exception.RenException; +import org.apache.commons.lang3.StringUtils; + +/** + * SQL过滤 + * @author Mark sunlightcs@gmail.com + */ +public class SqlFilter { + + /** + * SQL注入过滤 + * @param str 待验证的字符串 + */ + public static String sqlInject(String str){ + if(StringUtils.isBlank(str)){ + return null; + } + //去掉'|"|;|\字符 + str = StringUtils.replace(str, "'", ""); + str = StringUtils.replace(str, "\"", ""); + str = StringUtils.replace(str, ";", ""); + str = StringUtils.replace(str, "\\", ""); + + //转换成小写 + str = str.toLowerCase(); + + //非法字符 + String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"}; + + //判断是否包含非法字符 + for(String keyword : keywords){ + if(str.indexOf(keyword) != -1){ + throw new RenException(ErrorCode.INVALID_SYMBOL); + } + } + + return str; + } +} diff --git a/renren-common/src/main/java/io/renren/common/xss/XssFilter.java b/renren-common/src/main/java/io/renren/common/xss/XssFilter.java new file mode 100644 index 0000000..d9936c8 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/xss/XssFilter.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.xss; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * XSS过滤 + * @author Mark sunlightcs@gmail.com + */ +public class XssFilter implements Filter { + + @Override + public void init(FilterConfig config) { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper( + (HttpServletRequest) request); + chain.doFilter(xssRequest, response); + } + + @Override + public void destroy() { + } + +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java b/renren-common/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..515b917 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.xss; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Map; + + +/** + * XSS过滤处理 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + HttpServletRequest orgRequest; + + public XssHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + orgRequest = request; + } + + @Override + public ServletInputStream getInputStream() throws IOException { + //非json类型,直接返回 + if(!checkContentTypeIsJson()){ + return super.getInputStream(); + } + + //为空,直接返回 + String json = IOUtils.toString(super.getInputStream(), StandardCharsets.UTF_8); + if (StringUtils.isBlank(json)) { + return super.getInputStream(); + } + + //xss过滤 + json = xssEncode(json); + final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + return new ServletInputStream() { + @Override + public boolean isFinished() { + return true; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + + @Override + public int read() { + return bis.read(); + } + }; + } + + @Override + public String getParameter(String name) { + String value = super.getParameter(xssEncode(name)); + if (StringUtils.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + @Override + public String[] getParameterValues(String name) { + String[] parameters = super.getParameterValues(name); + if (parameters == null || parameters.length == 0) { + return null; + } + + for (int i = 0; i < parameters.length; i++) { + parameters[i] = xssEncode(parameters[i]); + } + return parameters; + } + + @Override + public Map getParameterMap() { + Map map = new LinkedHashMap<>(); + Map parameters = super.getParameterMap(); + for (String key : parameters.keySet()) { + String[] values = parameters.get(key); + for (int i = 0; i < values.length; i++) { + values[i] = xssEncode(values[i]); + } + map.put(key, values); + } + return map; + } + + @Override + public String getHeader(String name) { + String value = super.getHeader(xssEncode(name)); + if (StringUtils.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + private String xssEncode(String input) { + return XssUtils.filter(input); + } + + /** + * 获取最原始的request + */ + public HttpServletRequest getOrgRequest() { + return orgRequest; + } + + /** + * 获取最原始的request + */ + public static HttpServletRequest getOrgRequest(HttpServletRequest request) { + if (request instanceof XssHttpServletRequestWrapper) { + return ((XssHttpServletRequestWrapper) request).getOrgRequest(); + } + + return request; + } + /** + * 判断是否是json请求,以前缀的方式 + */ + private boolean checkContentTypeIsJson() + { + String header = super.getHeader(HttpHeaders.CONTENT_TYPE); + return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); + } +} \ No newline at end of file diff --git a/renren-common/src/main/java/io/renren/common/xss/XssUtils.java b/renren-common/src/main/java/io/renren/common/xss/XssUtils.java new file mode 100644 index 0000000..8a01255 --- /dev/null +++ b/renren-common/src/main/java/io/renren/common/xss/XssUtils.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.xss; + +import org.jsoup.Jsoup; +import org.jsoup.safety.Safelist; + +/** + * XSS过滤工具类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class XssUtils extends Safelist { + + /** + * XSS过滤 + */ + public static String filter(String html){ + return Jsoup.clean(html, xssWhitelist()); + } + + /** + * XSS过滤白名单 + */ + private static Safelist xssWhitelist(){ + return new Safelist() + //支持的标签 + .addTags("a", "b", "blockquote", "br", "caption", "cite", "code", "col", "colgroup", "dd", "div", "dl", + "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", "img", "li", "ol", "p", "pre", "q", "small", + "strike", "strong","sub", "sup", "table", "tbody", "td","tfoot", "th", "thead", "tr", "u","ul", + "embed","object","param","span") + + //支持的标签属性 + .addAttributes("a", "href", "class", "style", "target", "rel", "nofollow") + .addAttributes("blockquote", "cite") + .addAttributes("code", "class", "style") + .addAttributes("col", "span", "width") + .addAttributes("colgroup", "span", "width") + .addAttributes("img", "align", "alt", "height", "src", "title", "width", "class", "style") + .addAttributes("ol", "start", "type") + .addAttributes("q", "cite") + .addAttributes("table", "summary", "width", "class", "style") + .addAttributes("tr", "abbr", "axis", "colspan", "rowspan", "width", "style") + .addAttributes("td", "abbr", "axis", "colspan", "rowspan", "width", "style") + .addAttributes("th", "abbr", "axis", "colspan", "rowspan", "scope","width", "style") + .addAttributes("ul", "type", "style") + .addAttributes("pre", "class", "style") + .addAttributes("div", "class", "id", "style") + .addAttributes("embed", "src", "wmode", "flashvars", "pluginspage", "allowFullScreen", "allowfullscreen", + "quality", "width", "height", "align", "allowScriptAccess", "allowscriptaccess", "allownetworking", "type") + .addAttributes("object", "type", "id", "name", "data", "width", "height", "style", "classid", "codebase") + .addAttributes("param", "name", "value") + .addAttributes("span", "class", "style") + + //标签属性对应的协议 + .addProtocols("a", "href", "ftp", "http", "https", "mailto") + .addProtocols("img", "src", "http", "https") + .addProtocols("blockquote", "cite", "http", "https") + .addProtocols("cite", "cite", "http", "https") + .addProtocols("q", "cite", "http", "https") + .addProtocols("embed", "src", "http", "https"); + } + + public static void main(String[] args) { + StringBuilder html = new StringBuilder(); + html.append("人人开源"); + + System.out.println(filter(html.toString())); + } + +} \ No newline at end of file diff --git a/renren-common/src/main/resources/i18n/messages.properties b/renren-common/src/main/resources/i18n/messages.properties new file mode 100644 index 0000000..e4c723f --- /dev/null +++ b/renren-common/src/main/resources/i18n/messages.properties @@ -0,0 +1,26 @@ +#Default +500=\u670D\u52A1\u5668\u5185\u90E8\u5F02\u5E38 +401=\u672A\u6388\u6743 +10001={0}\u4E0D\u80FD\u4E3A\u7A7A +10002=\u6570\u636E\u5E93\u4E2D\u5DF2\u5B58\u5728\u8BE5\u8BB0\u5F55 +10003=\u83B7\u53D6\u53C2\u6570\u5931\u8D25 +10004=\u8D26\u53F7\u6216\u5BC6\u7801\u9519\u8BEF +10005=\u8D26\u53F7\u5DF2\u88AB\u505C\u7528 +10006=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A +10007=\u9A8C\u8BC1\u7801\u4E0D\u6B63\u786E +10008=\u5148\u5220\u9664\u5B50\u83DC\u5355\u6216\u6309\u94AE +10009=\u539F\u5BC6\u7801\u4E0D\u6B63\u786E +10010=\u8D26\u53F7\u4E0D\u5B58\u5728 +10011=\u4E0A\u7EA7\u90E8\u95E8\u9009\u62E9\u9519\u8BEF +10012=\u4E0A\u7EA7\u83DC\u5355\u4E0D\u80FD\u4E3A\u81EA\u8EAB +10013=\u6570\u636E\u6743\u9650\u63A5\u53E3\uFF0C\u53EA\u80FD\u662FMap\u7C7B\u578B\u53C2\u6570 +10014=\u8BF7\u5148\u5220\u9664\u4E0B\u7EA7\u90E8\u95E8 +10015=\u8BF7\u5148\u5220\u9664\u90E8\u95E8\u4E0B\u7684\u7528\u6237 +10019=\u8BF7\u4E0A\u4F20\u6587\u4EF6 +10020=token\u4E0D\u80FD\u4E3A\u7A7A +10021=token\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 +10022=\u8D26\u53F7\u5DF2\u88AB\u9501\u5B9A +10024=\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25{0} +10027=Redis\u670D\u52A1\u5F02\u5E38 +10028=\u5B9A\u65F6\u4EFB\u52A1\u5931\u8D25 +10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26 \ No newline at end of file diff --git a/renren-common/src/main/resources/i18n/validation.properties b/renren-common/src/main/resources/i18n/validation.properties new file mode 100644 index 0000000..e2c400d --- /dev/null +++ b/renren-common/src/main/resources/i18n/validation.properties @@ -0,0 +1,67 @@ +#\u7B80\u4F53\u4E2D\u6587 +id.require=ID\u4E0D\u80FD\u4E3A\u7A7A +id.null=ID\u5FC5\u987B\u4E3A\u7A7A +pid.require=\u4E0A\u7EA7ID\uFF0C\u4E0D\u80FD\u4E3A\u7A7A +sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u4E8E0 + +sysparams.paramcode.require=\u53C2\u6570\u7F16\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysparams.paramvalue.require=\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A + +sysuser.username.require=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.password.require=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.gender.range=\u6027\u522B\u53D6\u503C\u8303\u56F40~2 +sysuser.email.require=\u90AE\u7BB1\u4E0D\u80FD\u4E3A\u7A7A +sysuser.email.error=\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E +sysuser.mobile.require=\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A +sysuser.deptId.require=\u90E8\u95E8\u4E0D\u80FD\u4E3A\u7A7A +sysuser.superadmin.range=\u8D85\u7EA7\u7BA1\u7406\u5458\u53D6\u503C\u8303\u56F40~1 +sysuser.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 +sysuser.captcha.require=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysuser.uuid.require=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A + +sysmenu.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u83DC\u5355 +sysmenu.name.require=\u83DC\u5355\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +sysmenu.type.range=\u83DC\u5355\u7C7B\u578B\u53D6\u503C\u8303\u56F40~1 + +sysdept.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u90E8\u95E8 +sysdept.name.require=\u90E8\u95E8\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +sysrole.name.require=\u89D2\u8272\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +sysdict.label.require=\u5B57\u5178\u6807\u7B7E\u4E0D\u80FD\u4E3A\u7A7A + +schedule.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 +schedule.cron.require=cron\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A +schedule.bean.require=bean\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A + +oss.type.range=\u7C7B\u578B\u53D6\u503C\u8303\u56F41~3 + +aliyun.accesskeyid.require=\u963F\u91CC\u4E91AccessKeyId\u4E0D\u80FD\u4E3A\u7A7A +aliyun.accesskeysecret.require=\u963F\u91CC\u4E91AccessKeySecret\u4E0D\u80FD\u4E3A\u7A7A +aliyun.signname.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A +aliyun.templatecode.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u6A21\u677F\u4E0D\u80FD\u4E3A\u7A7A +aliyun.domain.require=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +aliyun.domain.url=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +aliyun.endPoint.require=\u963F\u91CC\u4E91EndPoint\u4E0D\u80FD\u4E3A\u7A7A +aliyun.bucketname.require=\u963F\u91CC\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A + +qcloud.appid.require=\u817E\u8BAF\u4E91AppId\u4E0D\u80FD\u4E3A\u7A7A +qcloud.appkey.require=\u817E\u8BAF\u4E91AppKey\u4E0D\u80FD\u4E3A\u7A7A +qcloud.secretId.require=\u817E\u8BAF\u4E91SecretId\u4E0D\u80FD\u4E3A\u7A7A +qcloud.secretkey.require=\u817E\u8BAF\u4E91SecretKey\u4E0D\u80FD\u4E3A\u7A7A +qcloud.signname.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A +qcloud.templateid.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A +qcloud.domain.require=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +qcloud.domain.url=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +qcloud.bucketname.require=\u817E\u8BAF\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A +qcloud.region.require=\u6240\u5C5E\u5730\u533A\u4E0D\u80FD\u4E3A\u7A7A + +qiniu.domain.require=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A +qiniu.domain.url=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E +qiniu.accesskey.require=\u4E03\u725BAccessKey\u4E0D\u80FD\u4E3A\u7A7A +qiniu.secretkey.require=\u4E03\u725BSecretKey\u4E0D\u80FD\u4E3A\u7A7A +qiniu.bucketname.require=\u4E03\u725B\u7A7A\u95F4\u540D\u4E0D\u80FD\u4E3A\u7A7A +qiniu.templateId.require=\u4E03\u725B\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A diff --git a/renren-dynamic-datasource/pom.xml b/renren-dynamic-datasource/pom.xml new file mode 100644 index 0000000..fd130a4 --- /dev/null +++ b/renren-dynamic-datasource/pom.xml @@ -0,0 +1,16 @@ + + + io.renren + renren-security + 5.2.0 + + 4.0.0 + renren-dynamic-datasource + jar + 多数据源 + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/annotation/DataSource.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/annotation/DataSource.java new file mode 100644 index 0000000..ea9a99c --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/annotation/DataSource.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.annotation; + +import java.lang.annotation.*; + +/** + * 多数据源注解 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource { + String value() default ""; +} diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/aspect/DataSourceAspect.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/aspect/DataSourceAspect.java new file mode 100644 index 0000000..9eda526 --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/aspect/DataSourceAspect.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.aspect; + +import io.renren.commons.dynamic.datasource.annotation.DataSource; +import io.renren.commons.dynamic.datasource.config.DynamicContextHolder; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; + +/** + * 多数据源,切面处理类 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Aspect +@Component +@Order(Ordered.HIGHEST_PRECEDENCE) +public class DataSourceAspect { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(io.renren.commons.dynamic.datasource.annotation.DataSource) " + + "|| @within(io.renren.commons.dynamic.datasource.annotation.DataSource)") + public void dataSourcePointCut() { + + } + + @Around("dataSourcePointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + MethodSignature signature = (MethodSignature) point.getSignature(); + Class targetClass = point.getTarget().getClass(); + Method method = signature.getMethod(); + + DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class); + DataSource methodDataSource = method.getAnnotation(DataSource.class); + if(targetDataSource != null || methodDataSource != null){ + String value; + if(methodDataSource != null){ + value = methodDataSource.value(); + }else { + value = targetDataSource.value(); + } + + DynamicContextHolder.push(value); + logger.debug("set datasource is {}", value); + } + + try { + return point.proceed(); + } finally { + DynamicContextHolder.poll(); + logger.debug("clean datasource"); + } + } +} \ No newline at end of file diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicContextHolder.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicContextHolder.java new file mode 100644 index 0000000..5633477 --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicContextHolder.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.config; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * 多数据源上下文 + * + * @author Mark sunlightcs@gmail.com + */ +public class DynamicContextHolder { + @SuppressWarnings("unchecked") + private static final ThreadLocal> CONTEXT_HOLDER = new ThreadLocal() { + @Override + protected Object initialValue() { + return new ArrayDeque(); + } + }; + + /** + * 获得当前线程数据源 + * + * @return 数据源名称 + */ + public static String peek() { + return CONTEXT_HOLDER.get().peek(); + } + + /** + * 设置当前线程数据源 + * + * @param dataSource 数据源名称 + */ + public static void push(String dataSource) { + CONTEXT_HOLDER.get().push(dataSource); + } + + /** + * 清空当前线程数据源 + */ + public static void poll() { + Deque deque = CONTEXT_HOLDER.get(); + deque.poll(); + if (deque.isEmpty()) { + CONTEXT_HOLDER.remove(); + } + } + +} \ No newline at end of file diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSource.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSource.java new file mode 100644 index 0000000..df40588 --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSource.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.config; + +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * 多数据源 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class DynamicDataSource extends AbstractRoutingDataSource { + + @Override + protected Object determineCurrentLookupKey() { + return DynamicContextHolder.peek(); + } + +} diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceConfig.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceConfig.java new file mode 100644 index 0000000..1de20b8 --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceConfig.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.config; + +import com.alibaba.druid.pool.DruidDataSource; +import io.renren.commons.dynamic.datasource.properties.DataSourceProperties; +import io.renren.commons.dynamic.datasource.properties.DynamicDataSourceProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.HashMap; +import java.util.Map; + +/** + * 配置多数据源 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@Configuration +@EnableConfigurationProperties(DynamicDataSourceProperties.class) +public class DynamicDataSourceConfig { + @Autowired + private DynamicDataSourceProperties properties; + + @Bean + @ConfigurationProperties(prefix = "spring.datasource.druid") + public DataSourceProperties dataSourceProperties() { + return new DataSourceProperties(); + } + + @Bean + public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) { + DynamicDataSource dynamicDataSource = new DynamicDataSource(); + dynamicDataSource.setTargetDataSources(getDynamicDataSource()); + + //默认数据源 + DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties); + dynamicDataSource.setDefaultTargetDataSource(defaultDataSource); + + return dynamicDataSource; + } + + private Map getDynamicDataSource(){ + Map dataSourcePropertiesMap = properties.getDatasource(); + Map targetDataSources = new HashMap<>(dataSourcePropertiesMap.size()); + dataSourcePropertiesMap.forEach((k, v) -> { + DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v); + targetDataSources.put(k, druidDataSource); + }); + + return targetDataSources; + } + +} \ No newline at end of file diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceFactory.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceFactory.java new file mode 100644 index 0000000..c73fab2 --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/config/DynamicDataSourceFactory.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.config; + +import com.alibaba.druid.pool.DruidDataSource; +import io.renren.commons.dynamic.datasource.properties.DataSourceProperties; + +import java.sql.SQLException; + +/** + * DruidDataSource + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class DynamicDataSourceFactory { + + public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) { + DruidDataSource druidDataSource = new DruidDataSource(); + druidDataSource.setDriverClassName(properties.getDriverClassName()); + druidDataSource.setUrl(properties.getUrl()); + druidDataSource.setUsername(properties.getUsername()); + druidDataSource.setPassword(properties.getPassword()); + + druidDataSource.setInitialSize(properties.getInitialSize()); + druidDataSource.setMaxActive(properties.getMaxActive()); + druidDataSource.setMinIdle(properties.getMinIdle()); + druidDataSource.setMaxWait(properties.getMaxWait()); + druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis()); + druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis()); + druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis()); + druidDataSource.setValidationQuery(properties.getValidationQuery()); + druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout()); + druidDataSource.setTestOnBorrow(properties.isTestOnBorrow()); + druidDataSource.setTestOnReturn(properties.isTestOnReturn()); + druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements()); + druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements()); + druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements()); + + try { + // druidDataSource.setFilters(properties.getFilters()); + druidDataSource.init(); + } catch (SQLException e) { + e.printStackTrace(); + } + return druidDataSource; + } +} \ No newline at end of file diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DataSourceProperties.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DataSourceProperties.java new file mode 100644 index 0000000..3e4d395 --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DataSourceProperties.java @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.properties; + +/** + * 多数据源属性 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +public class DataSourceProperties { + private String driverClassName; + private String url; + private String username; + private String password; + + /** + * Druid默认参数 + */ + private int initialSize = 2; + private int maxActive = 10; + private int minIdle = -1; + private long maxWait = 60 * 1000L; + private long timeBetweenEvictionRunsMillis = 60 * 1000L; + private long minEvictableIdleTimeMillis = 1000L * 60L * 30L; + private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7; + private String validationQuery = "select 1"; + private int validationQueryTimeout = -1; + private boolean testOnBorrow = false; + private boolean testOnReturn = false; + private boolean testWhileIdle = true; + private boolean poolPreparedStatements = false; + private int maxOpenPreparedStatements = -1; + private boolean sharePreparedStatements = false; + private String filters = "stat,wall"; + + public String getDriverClassName() { + return driverClassName; + } + + public void setDriverClassName(String driverClassName) { + this.driverClassName = driverClassName; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getInitialSize() { + return initialSize; + } + + public void setInitialSize(int initialSize) { + this.initialSize = initialSize; + } + + public int getMaxActive() { + return maxActive; + } + + public void setMaxActive(int maxActive) { + this.maxActive = maxActive; + } + + public int getMinIdle() { + return minIdle; + } + + public void setMinIdle(int minIdle) { + this.minIdle = minIdle; + } + + public long getMaxWait() { + return maxWait; + } + + public void setMaxWait(long maxWait) { + this.maxWait = maxWait; + } + + public long getTimeBetweenEvictionRunsMillis() { + return timeBetweenEvictionRunsMillis; + } + + public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { + this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; + } + + public long getMinEvictableIdleTimeMillis() { + return minEvictableIdleTimeMillis; + } + + public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { + this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; + } + + public long getMaxEvictableIdleTimeMillis() { + return maxEvictableIdleTimeMillis; + } + + public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) { + this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis; + } + + public String getValidationQuery() { + return validationQuery; + } + + public void setValidationQuery(String validationQuery) { + this.validationQuery = validationQuery; + } + + public int getValidationQueryTimeout() { + return validationQueryTimeout; + } + + public void setValidationQueryTimeout(int validationQueryTimeout) { + this.validationQueryTimeout = validationQueryTimeout; + } + + public boolean isTestOnBorrow() { + return testOnBorrow; + } + + public void setTestOnBorrow(boolean testOnBorrow) { + this.testOnBorrow = testOnBorrow; + } + + public boolean isTestOnReturn() { + return testOnReturn; + } + + public void setTestOnReturn(boolean testOnReturn) { + this.testOnReturn = testOnReturn; + } + + public boolean isTestWhileIdle() { + return testWhileIdle; + } + + public void setTestWhileIdle(boolean testWhileIdle) { + this.testWhileIdle = testWhileIdle; + } + + public boolean isPoolPreparedStatements() { + return poolPreparedStatements; + } + + public void setPoolPreparedStatements(boolean poolPreparedStatements) { + this.poolPreparedStatements = poolPreparedStatements; + } + + public int getMaxOpenPreparedStatements() { + return maxOpenPreparedStatements; + } + + public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) { + this.maxOpenPreparedStatements = maxOpenPreparedStatements; + } + + public boolean isSharePreparedStatements() { + return sharePreparedStatements; + } + + public void setSharePreparedStatements(boolean sharePreparedStatements) { + this.sharePreparedStatements = sharePreparedStatements; + } + + public String getFilters() { + return filters; + } + + public void setFilters(String filters) { + this.filters = filters; + } +} \ No newline at end of file diff --git a/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DynamicDataSourceProperties.java b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DynamicDataSourceProperties.java new file mode 100644 index 0000000..bc97020 --- /dev/null +++ b/renren-dynamic-datasource/src/main/java/io/renren/commons/dynamic/datasource/properties/DynamicDataSourceProperties.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.commons.dynamic.datasource.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 多数据源属性 + * + * @author Mark sunlightcs@gmail.com + * @since 1.0.0 + */ +@ConfigurationProperties(prefix = "dynamic") +public class DynamicDataSourceProperties { + private Map datasource = new LinkedHashMap<>(); + + public Map getDatasource() { + return datasource; + } + + public void setDatasource(Map datasource) { + this.datasource = datasource; + } +} diff --git a/renren-generator/pom.xml b/renren-generator/pom.xml new file mode 100644 index 0000000..adb152c --- /dev/null +++ b/renren-generator/pom.xml @@ -0,0 +1,135 @@ + + + 4.0.0 + io.renren + renren-generator + 5.2.0 + jar + renren-generator + + + org.springframework.boot + spring-boot-starter-parent + 2.7.5 + + + + UTF-8 + UTF-8 + 1.8 + 2.2.2 + 1.4.2 + 1.2.14 + 2.6 + 2.11.0 + 1.10 + 1.7 + 4.0 + 11.2.0.3 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis.spring.boot.version} + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.spring.boot.version} + + + com.alibaba + druid + ${druid.version} + + + commons-lang + commons-lang + ${commons.lang.version} + + + commons-io + commons-io + ${commons.io.version} + + + commons-configuration + commons-configuration + ${commons.configuration.version} + + + velocity + org.apache.velocity + ${velocity.version} + + + + mysql + mysql-connector-java + + + + com.oracle + ojdbc6 + ${oracle.version} + + + + com.microsoft.sqlserver + sqljdbc4 + ${mssql.version} + + + + org.postgresql + postgresql + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public/ + + true + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public/ + + true + + + false + + + + + diff --git a/renren-generator/src/main/java/io/renren/GeneratorApplication.java b/renren-generator/src/main/java/io/renren/GeneratorApplication.java new file mode 100644 index 0000000..c0dc876 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/GeneratorApplication.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * renren-generator + * + * @author Mark sunlightcs@gmail.com + */ +@SpringBootApplication +public class GeneratorApplication { + + public static void main(String[] args) { + SpringApplication.run(GeneratorApplication.class, args); + } +} diff --git a/renren-generator/src/main/java/io/renren/config/DbConfig.java b/renren-generator/src/main/java/io/renren/config/DbConfig.java new file mode 100644 index 0000000..5b67693 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/config/DbConfig.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import io.renren.dao.*; +import io.renren.utils.RenException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +/** + * 数据库配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class DbConfig { + @Value("${renren.database: mysql}") + private String database; + @Autowired + private MySQLGeneratorDao mySQLGeneratorDao; + @Autowired + private OracleGeneratorDao oracleGeneratorDao; + @Autowired + private SQLServerGeneratorDao sqlServerGeneratorDao; + @Autowired + private PostgreSQLGeneratorDao postgreSQLGeneratorDao; + + @Bean + @Primary + public GeneratorDao getGeneratorDao(){ + if("mysql".equalsIgnoreCase(database)){ + return mySQLGeneratorDao; + }else if("oracle".equalsIgnoreCase(database)){ + return oracleGeneratorDao; + }else if("sqlserver".equalsIgnoreCase(database)){ + return sqlServerGeneratorDao; + }else if("postgresql".equalsIgnoreCase(database)){ + return postgreSQLGeneratorDao; + }else { + throw new RenException("不支持当前数据库:" + database); + } + } +} diff --git a/renren-generator/src/main/java/io/renren/controller/SysGeneratorController.java b/renren-generator/src/main/java/io/renren/controller/SysGeneratorController.java new file mode 100644 index 0000000..7baef11 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/controller/SysGeneratorController.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.controller; + +import io.renren.service.SysGeneratorService; +import io.renren.utils.PageUtils; +import io.renren.utils.Query; +import io.renren.utils.R; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Map; + +/** + * 代码生成器 + * + * @author Mark sunlightcs@gmail.com + */ +@Controller +@RequestMapping("/sys/generator") +public class SysGeneratorController { + @Autowired + private SysGeneratorService sysGeneratorService; + + /** + * 列表 + */ + @ResponseBody + @RequestMapping("/list") + public R list(@RequestParam Map params){ + PageUtils pageUtil = sysGeneratorService.queryList(new Query(params)); + + return R.ok().put("page", pageUtil); + } + + /** + * 生成代码 + */ + @RequestMapping("/code") + public void code(String tables, HttpServletResponse response) throws IOException{ + byte[] data = sysGeneratorService.generatorCode(tables.split(",")); + + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"renren.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + + IOUtils.write(data, response.getOutputStream()); + } +} diff --git a/renren-generator/src/main/java/io/renren/dao/GeneratorDao.java b/renren-generator/src/main/java/io/renren/dao/GeneratorDao.java new file mode 100644 index 0000000..f9f2335 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/dao/GeneratorDao.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dao; + +import java.util.List; +import java.util.Map; + +/** + * 数据库接口 + * + * @author Mark sunlightcs@gmail.com + */ +public interface GeneratorDao { + List> queryList(Map map); + + Map queryTable(String tableName); + + List> queryColumns(String tableName); +} diff --git a/renren-generator/src/main/java/io/renren/dao/MySQLGeneratorDao.java b/renren-generator/src/main/java/io/renren/dao/MySQLGeneratorDao.java new file mode 100644 index 0000000..65c4ad5 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/dao/MySQLGeneratorDao.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dao; + +import org.apache.ibatis.annotations.Mapper; + + +/** + * MySQL代码生成器 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface MySQLGeneratorDao extends GeneratorDao { + + +} diff --git a/renren-generator/src/main/java/io/renren/dao/OracleGeneratorDao.java b/renren-generator/src/main/java/io/renren/dao/OracleGeneratorDao.java new file mode 100644 index 0000000..effd14c --- /dev/null +++ b/renren-generator/src/main/java/io/renren/dao/OracleGeneratorDao.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dao; + +import org.apache.ibatis.annotations.Mapper; + +/** + * Oracle代码生成器 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface OracleGeneratorDao extends GeneratorDao { + +} diff --git a/renren-generator/src/main/java/io/renren/dao/PostgreSQLGeneratorDao.java b/renren-generator/src/main/java/io/renren/dao/PostgreSQLGeneratorDao.java new file mode 100644 index 0000000..14ad34b --- /dev/null +++ b/renren-generator/src/main/java/io/renren/dao/PostgreSQLGeneratorDao.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dao; + +import org.apache.ibatis.annotations.Mapper; + +/** + * PostgreSQL代码生成器 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface PostgreSQLGeneratorDao extends GeneratorDao { + +} diff --git a/renren-generator/src/main/java/io/renren/dao/SQLServerGeneratorDao.java b/renren-generator/src/main/java/io/renren/dao/SQLServerGeneratorDao.java new file mode 100644 index 0000000..ec9c5b5 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/dao/SQLServerGeneratorDao.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.dao; + +import org.apache.ibatis.annotations.Mapper; + +/** + * SQLServer代码生成器 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SQLServerGeneratorDao extends GeneratorDao { + +} diff --git a/renren-generator/src/main/java/io/renren/entity/ColumnEntity.java b/renren-generator/src/main/java/io/renren/entity/ColumnEntity.java new file mode 100644 index 0000000..04fffc4 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/entity/ColumnEntity.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.entity; + +/** + * 列的属性 + * + * @author Mark sunlightcs@gmail.com + */ +public class ColumnEntity { + //列名 + private String columnName; + //列名类型 + private String dataType; + //列名备注 + private String comments; + + //属性名称(第一个字母大写),如:user_name => UserName + private String attrName; + //属性名称(第一个字母小写),如:user_name => userName + private String attrname; + //属性类型 + private String attrType; + //auto_increment + private String extra; + + public String getColumnName() { + return columnName; + } + public void setColumnName(String columnName) { + this.columnName = columnName; + } + public String getDataType() { + return dataType; + } + public void setDataType(String dataType) { + this.dataType = dataType; + } + public String getComments() { + return comments; + } + public void setComments(String comments) { + this.comments = comments; + } + public String getAttrname() { + return attrname; + } + public void setAttrname(String attrname) { + this.attrname = attrname; + } + public String getAttrName() { + return attrName; + } + public void setAttrName(String attrName) { + this.attrName = attrName; + } + public String getAttrType() { + return attrType; + } + public void setAttrType(String attrType) { + this.attrType = attrType; + } + public String getExtra() { + return extra; + } + public void setExtra(String extra) { + this.extra = extra; + } +} diff --git a/renren-generator/src/main/java/io/renren/entity/TableEntity.java b/renren-generator/src/main/java/io/renren/entity/TableEntity.java new file mode 100644 index 0000000..a36289f --- /dev/null +++ b/renren-generator/src/main/java/io/renren/entity/TableEntity.java @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.entity; + +import java.util.List; + +/** + * 表数据 + * + * @author Mark sunlightcs@gmail.com + */ +public class TableEntity { + //表的名称 + private String tableName; + //表的备注 + private String comments; + //表的主键 + private ColumnEntity pk; + //表的列名(不包含主键) + private List columns; + + //类名(第一个字母大写),如:sys_user => SysUser + private String className; + //类名(第一个字母小写),如:sys_user => sysUser + private String classname; + + public String getTableName() { + return tableName; + } + public void setTableName(String tableName) { + this.tableName = tableName; + } + public String getComments() { + return comments; + } + public void setComments(String comments) { + this.comments = comments; + } + public ColumnEntity getPk() { + return pk; + } + public void setPk(ColumnEntity pk) { + this.pk = pk; + } + public List getColumns() { + return columns; + } + public void setColumns(List columns) { + this.columns = columns; + } + public String getClassName() { + return className; + } + public void setClassName(String className) { + this.className = className; + } + public String getClassname() { + return classname; + } + public void setClassname(String classname) { + this.classname = classname; + } +} diff --git a/renren-generator/src/main/java/io/renren/service/SysGeneratorService.java b/renren-generator/src/main/java/io/renren/service/SysGeneratorService.java new file mode 100644 index 0000000..dd6ba66 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/service/SysGeneratorService.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.service; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import io.renren.dao.GeneratorDao; +import io.renren.utils.GenUtils; +import io.renren.utils.PageUtils; +import io.renren.utils.Query; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipOutputStream; + +/** + * 代码生成器 + * + * @author Mark sunlightcs@gmail.com + */ +@Service +public class SysGeneratorService { + @Autowired + private GeneratorDao generatorDao; + + public PageUtils queryList(Query query) { + Page page = PageHelper.startPage(query.getPage(), query.getLimit()); + List> list = generatorDao.queryList(query); + + return new PageUtils(list, (int)page.getTotal(), query.getLimit(), query.getPage()); + } + + public Map queryTable(String tableName) { + return generatorDao.queryTable(tableName); + } + + public List> queryColumns(String tableName) { + return generatorDao.queryColumns(tableName); + } + + public byte[] generatorCode(String[] tableNames) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + + for(String tableName : tableNames){ + //查询表信息 + Map table = queryTable(tableName); + //查询列信息 + List> columns = queryColumns(tableName); + //生成代码 + GenUtils.generatorCode(table, columns, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } +} diff --git a/renren-generator/src/main/java/io/renren/utils/Assert.java b/renren-generator/src/main/java/io/renren/utils/Assert.java new file mode 100644 index 0000000..295343b --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/Assert.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.renren.utils; + + +/** + *

+ * 断言类 + *

+ * + * @author miemie + * @since 2018-07-24 + */ +public final class Assert { + + /** + * 断言这个 boolean 为 true + * 为 false 则抛出异常 + * + * @param expression boolean 值 + * @param message 消息 + */ + public static void isTrue(boolean expression, String message, Object... params) { + if (!expression) { + return; + } + } + + /** + * 断言这个 boolean 为 false + * 为 true 则抛出异常 + * + * @param expression boolean 值 + * @param message 消息 + */ + public static void isFalse(boolean expression, String message, Object... params) { + isTrue(!expression, message, params); + } + + /** + * 断言这个 object 为 null + * 不为 null 则抛异常 + * + * @param object 对象 + * @param message 消息 + */ + public static void isNull(Object object, String message, Object... params) { + isTrue(object == null, message, params); + } + + /** + * 断言这个 object 不为 null + * 为 null 则抛异常 + * + * @param object 对象 + * @param message 消息 + */ + public static void notNull(Object object, String message, Object... params) { + isTrue(object != null, message, params); + } + + +} diff --git a/renren-generator/src/main/java/io/renren/utils/DateUtils.java b/renren-generator/src/main/java/io/renren/utils/DateUtils.java new file mode 100644 index 0000000..4992d42 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/DateUtils.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.utils; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 日期处理 + * + * @author Mark sunlightcs@gmail.com + */ +public class DateUtils { + /** 时间格式(yyyy-MM-dd) */ + public final static String DATE_PATTERN = "yyyy-MM-dd"; + /** 时间格式(yyyy-MM-dd HH:mm:ss) */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + public static String format(Date date) { + return format(date, DATE_PATTERN); + } + + public static String format(Date date, String pattern) { + if(date != null){ + SimpleDateFormat df = new SimpleDateFormat(pattern); + return df.format(date); + } + return null; + } +} diff --git a/renren-generator/src/main/java/io/renren/utils/GenUtils.java b/renren-generator/src/main/java/io/renren/utils/GenUtils.java new file mode 100644 index 0000000..27793f0 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/GenUtils.java @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.utils; + +import io.renren.entity.ColumnEntity; +import io.renren.entity.TableEntity; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.WordUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * 代码生成器 工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class GenUtils { + + public static List getTemplates(){ + List templates = new ArrayList(); + templates.add("template/DTO.java.vm"); + templates.add("template/Entity.java.vm"); + templates.add("template/Dao.java.vm"); + templates.add("template/Dao.xml.vm"); + templates.add("template/Service.java.vm"); + templates.add("template/ServiceImpl.java.vm"); + templates.add("template/Controller.java.vm"); + templates.add("template/Excel.java.vm"); + templates.add("template/index.vue.vm"); + templates.add("template/add-or-update.vue.vm"); + templates.add("template/mysql.vm"); + templates.add("template/sqlserver.vm"); + templates.add("template/oracle.vm"); + templates.add("template/postgresql.vm"); + return templates; + } + + /** + * 生成代码 + */ + public static void generatorCode(Map table, + List> columns, ZipOutputStream zip){ + //配置信息 + Configuration config = getConfig(); + boolean hasBigDecimal = false; + //表信息 + TableEntity tableEntity = new TableEntity(); + tableEntity.setTableName(table.get("tableName")); + tableEntity.setComments(table.get("tableComment")); + //表名转换成Java类名 + String className = tableToJava(tableEntity.getTableName(), config.getString("tablePrefix")); + tableEntity.setClassName(className); + tableEntity.setClassname(StringUtils.uncapitalize(className)); + + //列信息 + List columnsList = new ArrayList<>(); + for(Map column : columns){ + ColumnEntity columnEntity = new ColumnEntity(); + columnEntity.setColumnName(column.get("columnName")); + columnEntity.setDataType(column.get("dataType")); + columnEntity.setComments(column.get("columnComment")); + columnEntity.setExtra(column.get("extra")); + + //列名转换成Java属性名 + String attrName = columnToJava(columnEntity.getColumnName()); + columnEntity.setAttrName(attrName); + columnEntity.setAttrname(StringUtils.uncapitalize(attrName)); + + //列的数据类型,转换成Java类型 + String attrType = config.getString(columnEntity.getDataType(), "unknowType"); + columnEntity.setAttrType(attrType); + if (!hasBigDecimal && attrType.equals("BigDecimal" )) { + hasBigDecimal = true; + } + //是否主键 + if("PRI".equalsIgnoreCase(column.get("columnKey")) && tableEntity.getPk() == null){ + tableEntity.setPk(columnEntity); + } + + columnsList.add(columnEntity); + } + tableEntity.setColumns(columnsList); + + //没主键,则第一个字段为主键 + if(tableEntity.getPk() == null){ + tableEntity.setPk(tableEntity.getColumns().get(0)); + } + + //设置velocity资源加载器 + Properties prop = new Properties(); + prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + Velocity.init(prop); + + //封装模板数据 + Map map = new HashMap<>(); + map.put("tableName", tableEntity.getTableName()); + map.put("comments", tableEntity.getComments()); + map.put("pk", tableEntity.getPk()); + map.put("className", tableEntity.getClassName()); + map.put("classname", tableEntity.getClassname()); + map.put("pathName", tableEntity.getClassname().toLowerCase()); + map.put("columns", tableEntity.getColumns()); + map.put("hasBigDecimal", hasBigDecimal); + map.put("version", config.getString("version" )); + map.put("package", config.getString("package" )); + map.put("moduleName", config.getString("moduleName" )); + map.put("author", config.getString("author")); + map.put("email", config.getString("email")); + map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)); + map.put("date", DateUtils.format(new Date(), DateUtils.DATE_PATTERN)); + + for(int i=0; i<=10; i++){ + map.put("id"+i, IdWorker.getId()); + } + + VelocityContext context = new VelocityContext(map); + + //获取模板列表 + List templates = getTemplates(); + for(String template : templates){ + //渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, "UTF-8"); + tpl.merge(context, sw); + + try { + //添加到zip + zip.putNextEntry(new ZipEntry(getFileName(template, tableEntity.getClassName(), config.getString("package"), config.getString("moduleName")))); + IOUtils.write(sw.toString(), zip, "UTF-8"); + IOUtils.closeQuietly(sw); + zip.closeEntry(); + } catch (IOException e) { + throw new RenException("渲染模板失败,表名:" + tableEntity.getTableName(), e); + } + } + } + + + /** + * 列名转换成Java属性名 + */ + public static String columnToJava(String columnName) { + return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", ""); + } + + /** + * 表名转换成Java类名 + */ + public static String tableToJava(String tableName, String tablePrefix) { + if(StringUtils.isNotBlank(tablePrefix)){ + tableName = tableName.startsWith(tablePrefix) ? tableName.replaceFirst(tablePrefix, "") : tableName; + } + return columnToJava(tableName); + } + + /** + * 获取配置信息 + */ + public static Configuration getConfig(){ + try { + return new PropertiesConfiguration("generator.properties"); + } catch (ConfigurationException e) { + throw new RenException("获取配置文件失败,", e); + } + } + + /** + * 获取文件名 + */ + public static String getFileName(String template, String className, String packageName, String moduleName) { + String packagePath = "main" + File.separator + "java" + File.separator; + if (StringUtils.isNotBlank(packageName)) { + packagePath += packageName.replace(".", File.separator) + File.separator + "modules" + File.separator + moduleName + File.separator; + } + + if (template.contains("Entity.java.vm" )) { + return packagePath + "entity" + File.separator + className + "Entity.java"; + } + + if (template.contains("Excel.java.vm" )) { + return packagePath + "excel" + File.separator + className + "Excel.java"; + } + + if (template.contains("Dao.java.vm" )) { + return packagePath + "dao" + File.separator + className + "Dao.java"; + } + + if (template.contains("Service.java.vm" )) { + return packagePath + "service" + File.separator + className + "Service.java"; + } + + if (template.contains("ServiceImpl.java.vm" )) { + return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; + } + + if (template.contains("Controller.java.vm" )) { + return packagePath + "controller" + File.separator + className + "Controller.java"; + } + + if (template.contains("Dao.xml.vm" )) { + return "main" + File.separator + "resources" + File.separator + "mapper" + File.separator + moduleName + File.separator + className + "Dao.xml"; + } + + if (template.contains("DTO.java.vm" )) { + return packagePath + "dto" + File.separator + className + "DTO.java"; + } + + if (template.contains("index.vue.vm" )) { + return "vue" + File.separator + "views" + File.separator + "modules" + + File.separator + moduleName + File.separator + className.toLowerCase() + ".vue"; + } + + if (template.contains("add-or-update.vue.vm" )) { + return "vue" + File.separator + "views" + File.separator + "modules" + + File.separator + moduleName + File.separator + className.toLowerCase() + "-add-or-update.vue"; + } + + if (template.contains("mysql.vm" )) { + return className.toLowerCase() + ".mysql.sql"; + } + + if (template.contains("oracle.vm" )) { + return className.toLowerCase() + ".oracle.sql"; + } + + if (template.contains("sqlserver.vm" )) { + return className.toLowerCase() + ".sqlserver.sql"; + } + + if (template.contains("postgresql.vm" )) { + return className.toLowerCase() + ".postgresql.sql"; + } + + return null; + } +} diff --git a/renren-generator/src/main/java/io/renren/utils/IdWorker.java b/renren-generator/src/main/java/io/renren/utils/IdWorker.java new file mode 100644 index 0000000..ab649c3 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/IdWorker.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011-2020, hubin (jobob@qq.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.renren.utils; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + *

+ * 高效GUID产生算法(sequence),基于Snowflake实现64位自增ID算法。
+ * 优化开源项目 http://git.oschina.net/yu120/sequence + *

+ * + * @author hubin + * @since 2016-08-01 + */ +public class IdWorker { + + /** + * 主机和进程的机器码 + */ + private static Sequence WORKER = new Sequence(); + + public static long getId() { + return WORKER.nextId(); + } + + public static String getIdStr() { + return String.valueOf(WORKER.nextId()); + } + + /** + *

+ * 有参构造器 + *

+ * + * @param workerId 工作机器 ID + * @param datacenterId 序列号 + */ + public static void initSequence(long workerId, long datacenterId) { + WORKER = new Sequence(workerId, datacenterId); + } + + /** + *

+ * 使用ThreadLocalRandom获取UUID获取更优的效果 去掉"-" + *

+ */ + public static String get32UUID() { + ThreadLocalRandom random = ThreadLocalRandom.current(); + return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY); + } + +} diff --git a/renren-generator/src/main/java/io/renren/utils/PageUtils.java b/renren-generator/src/main/java/io/renren/utils/PageUtils.java new file mode 100644 index 0000000..d28ee9f --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/PageUtils.java @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.utils; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class PageUtils implements Serializable { + private static final long serialVersionUID = 1L; + //总记录数 + private int totalCount; + //每页记录数 + private int pageSize; + //总页数 + private int totalPage; + //当前页数 + private int currPage; + //列表数据 + private List list; + + /** + * 分页 + * @param list 列表数据 + * @param totalCount 总记录数 + * @param pageSize 每页记录数 + * @param currPage 当前页数 + */ + public PageUtils(List list, int totalCount, int pageSize, int currPage) { + this.list = list; + this.totalCount = totalCount; + this.pageSize = pageSize; + this.currPage = currPage; + this.totalPage = (int)Math.ceil((double)totalCount/pageSize); + } + + public int getTotalCount() { + return totalCount; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public int getTotalPage() { + return totalPage; + } + + public void setTotalPage(int totalPage) { + this.totalPage = totalPage; + } + + public int getCurrPage() { + return currPage; + } + + public void setCurrPage(int currPage) { + this.currPage = currPage; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + +} diff --git a/renren-generator/src/main/java/io/renren/utils/Query.java b/renren-generator/src/main/java/io/renren/utils/Query.java new file mode 100644 index 0000000..a932f9b --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/Query.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.utils; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 查询参数 + * + * @author Mark sunlightcs@gmail.com + */ +public class Query extends LinkedHashMap { + private static final long serialVersionUID = 1L; + //当前页码 + private int page; + //每页条数 + private int limit; + + public Query(Map params){ + this.putAll(params); + + //分页参数 + this.page = Integer.parseInt(params.get("page").toString()); + this.limit = Integer.parseInt(params.get("limit").toString()); + this.put("offset", (page - 1) * limit); + this.put("page", page); + this.put("limit", limit); + } + + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } +} diff --git a/renren-generator/src/main/java/io/renren/utils/R.java b/renren-generator/src/main/java/io/renren/utils/R.java new file mode 100644 index 0000000..5d8d90b --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/R.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * 返回数据 + * + * @author Mark sunlightcs@gmail.com + */ +public class R extends HashMap { + private static final long serialVersionUID = 1L; + + public R() { + put("code", 0); + } + + public static R error() { + return error(500, "未知异常,请联系管理员"); + } + + public static R error(String msg) { + return error(500, msg); + } + + public static R error(int code, String msg) { + R r = new R(); + r.put("code", code); + r.put("msg", msg); + return r; + } + + public static R ok(String msg) { + R r = new R(); + r.put("msg", msg); + return r; + } + + public static R ok(Map map) { + R r = new R(); + r.putAll(map); + return r; + } + + public static R ok() { + return new R(); + } + + @Override + public R put(String key, Object value) { + super.put(key, value); + return this; + } +} diff --git a/renren-generator/src/main/java/io/renren/utils/RenException.java b/renren-generator/src/main/java/io/renren/utils/RenException.java new file mode 100644 index 0000000..0275a4a --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/RenException.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.utils; + +/** + * 自定义异常 + * + * @author Mark sunlightcs@gmail.com + */ +public class RenException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private String msg; + private int code = 500; + + public RenException(String msg) { + super(msg); + this.msg = msg; + } + + public RenException(String msg, Throwable e) { + super(msg, e); + this.msg = msg; + } + + public RenException(String msg, int code) { + super(msg); + this.msg = msg; + this.code = code; + } + + public RenException(String msg, int code, Throwable e) { + super(msg, e); + this.msg = msg; + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + +} diff --git a/renren-generator/src/main/java/io/renren/utils/RenExceptionHandler.java b/renren-generator/src/main/java/io/renren/utils/RenExceptionHandler.java new file mode 100644 index 0000000..27a3822 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/RenExceptionHandler.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 异常处理器 + * + * @author Mark sunlightcs@gmail.com + */ +@RestControllerAdvice +public class RenExceptionHandler { + private Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * 处理自定义异常 + */ + @ExceptionHandler(RenException.class) + public R handleRenException(RenException e){ + R r = new R(); + r.put("code", e.getCode()); + r.put("msg", e.getMessage()); + + return r; + } + + @ExceptionHandler(Exception.class) + public R handleException(Exception e){ + logger.error(e.getMessage(), e); + return R.error(); + } +} diff --git a/renren-generator/src/main/java/io/renren/utils/Sequence.java b/renren-generator/src/main/java/io/renren/utils/Sequence.java new file mode 100644 index 0000000..21a3b9b --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/Sequence.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2011-2020, hubin (jobob@qq.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.renren.utils; + +import org.apache.commons.lang.StringUtils; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.concurrent.ThreadLocalRandom; + +/** + *

+ * 分布式高效有序ID生产黑科技(sequence)
+ * 优化开源项目:http://git.oschina.net/yu120/sequence + *

+ * + * @author hubin + * @since 2016-08-18 + */ +public class Sequence { + + private static final Log logger = LogFactory.getLog(Sequence.class); + /** + * 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动) + */ + private final long twepoch = 1288834974657L; + /** + * 机器标识位数 + */ + private final long workerIdBits = 5L; + private final long datacenterIdBits = 5L; + private final long maxWorkerId = -1L ^ (-1L << workerIdBits); + private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + /** + * 毫秒内自增位 + */ + private final long sequenceBits = 12L; + private final long workerIdShift = sequenceBits; + private final long datacenterIdShift = sequenceBits + workerIdBits; + /** + * 时间戳左移动位 + */ + private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + private final long sequenceMask = -1L ^ (-1L << sequenceBits); + + private final long workerId; + + /** + * 数据标识 ID 部分 + */ + private final long datacenterId; + /** + * 并发控制 + */ + private long sequence = 0L; + /** + * 上次生产 ID 时间戳 + */ + private long lastTimestamp = -1L; + + public Sequence() { + this.datacenterId = getDatacenterId(maxDatacenterId); + this.workerId = getMaxWorkerId(datacenterId, maxWorkerId); + } + + /** + *

+ * 有参构造器 + *

+ * + * @param workerId 工作机器 ID + * @param datacenterId 序列号 + */ + public Sequence(long workerId, long datacenterId) { + Assert.isFalse(workerId > maxWorkerId || workerId < 0, + String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + Assert.isFalse(datacenterId > maxDatacenterId || datacenterId < 0, + String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + /** + *

+ * 获取 maxWorkerId + *

+ */ + protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) { + StringBuilder mpid = new StringBuilder(); + mpid.append(datacenterId); + String name = ManagementFactory.getRuntimeMXBean().getName(); + if (StringUtils.isNotEmpty(name)) { + /* + * GET jvmPid + */ + mpid.append(name.split(StringPool.AT)[0]); + } + /* + * MAC + PID 的 hashcode 获取16个低位 + */ + return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1); + } + + /** + *

+ * 数据标识id部分 + *

+ */ + protected static long getDatacenterId(long maxDatacenterId) { + long id = 0L; + try { + InetAddress ip = InetAddress.getLocalHost(); + NetworkInterface network = NetworkInterface.getByInetAddress(ip); + if (network == null) { + id = 1L; + } else { + byte[] mac = network.getHardwareAddress(); + if (null != mac) { + id = ((0x000000FF & (long) mac[mac.length - 1]) | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6; + id = id % (maxDatacenterId + 1); + } + } + } catch (Exception e) { + logger.warn(" getDatacenterId: " + e.getMessage()); + } + return id; + } + + /** + * 获取下一个ID + * + * @return + */ + public synchronized long nextId() { + long timestamp = timeGen(); + //闰秒 + if (timestamp < lastTimestamp) { + long offset = lastTimestamp - timestamp; + if (offset <= 5) { + try { + wait(offset << 1); + timestamp = timeGen(); + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset)); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset)); + } + } + + if (lastTimestamp == timestamp) { + // 相同毫秒内,序列号自增 + sequence = (sequence + 1) & sequenceMask; + if (sequence == 0) { + // 同一毫秒的序列数已经达到最大 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + // 不同毫秒内,序列号置为 1 - 3 随机数 + sequence = ThreadLocalRandom.current().nextLong(1, 3); + } + + lastTimestamp = timestamp; + + // 时间戳部分 | 数据中心部分 | 机器标识部分 | 序列号部分 + return ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + protected long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + protected long timeGen() { + return SystemClock.now(); + } + +} diff --git a/renren-generator/src/main/java/io/renren/utils/StringPool.java b/renren-generator/src/main/java/io/renren/utils/StringPool.java new file mode 100644 index 0000000..f8bcc27 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/StringPool.java @@ -0,0 +1,95 @@ +package io.renren.utils; + +/** + * Copy to jodd.util + *

+ * Pool of String constants to prevent repeating of + * hard-coded String literals in the code. + * Due to fact that these are public static final + * they will be inlined by java compiler and + * reference to this class will be dropped. + * There is no performance gain of using this pool. + * Read: http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5 + *

    + *
  • Literal strings within the same class in the same package represent references to the same String object.
  • + *
  • Literal strings within different classes in the same package represent references to the same String object.
  • + *
  • Literal strings within different classes in different packages likewise represent references to the same String object.
  • + *
  • Strings computed by constant expressions are computed at compile time and then treated as if they were literals.
  • + *
  • Strings computed by concatenation at run time are newly created and therefore distinct.
  • + *
+ */ +public interface StringPool { + + String AMPERSAND = "&"; + String AND = "and"; + String AT = "@"; + String ASTERISK = "*"; + String STAR = ASTERISK; + String BACK_SLASH = "\\"; + String COLON = ":"; + String COMMA = ","; + String DASH = "-"; + String DOLLAR = "$"; + String DOT = "."; + String DOTDOT = ".."; + String DOT_CLASS = ".class"; + String DOT_JAVA = ".java"; + String DOT_XML = ".xml"; + String EMPTY = ""; + String EQUALS = "="; + String FALSE = "false"; + String SLASH = "/"; + String HASH = "#"; + String HAT = "^"; + String LEFT_BRACE = "{"; + String LEFT_BRACKET = "("; + String LEFT_CHEV = "<"; + String NEWLINE = "\n"; + String N = "n"; + String NO = "no"; + String NULL = "null"; + String OFF = "off"; + String ON = "on"; + String PERCENT = "%"; + String PIPE = "|"; + String PLUS = "+"; + String QUESTION_MARK = "?"; + String EXCLAMATION_MARK = "!"; + String QUOTE = "\""; + String RETURN = "\r"; + String TAB = "\t"; + String RIGHT_BRACE = "}"; + String RIGHT_BRACKET = ")"; + String RIGHT_CHEV = ">"; + String SEMICOLON = ";"; + String SINGLE_QUOTE = "'"; + String BACKTICK = "`"; + String SPACE = " "; + String TILDA = "~"; + String LEFT_SQ_BRACKET = "["; + String RIGHT_SQ_BRACKET = "]"; + String TRUE = "true"; + String UNDERSCORE = "_"; + String UTF_8 = "UTF-8"; + String US_ASCII = "US-ASCII"; + String ISO_8859_1 = "ISO-8859-1"; + String Y = "y"; + String YES = "yes"; + String ONE = "1"; + String ZERO = "0"; + String DOLLAR_LEFT_BRACE = "${"; + String HASH_LEFT_BRACE = "#{"; + String CRLF = "\r\n"; + + String HTML_NBSP = " "; + String HTML_AMP = "&"; + String HTML_QUOTE = """; + String HTML_LT = "<"; + String HTML_GT = ">"; + + // ---------------------------------------------------------------- array + + String[] EMPTY_ARRAY = new String[0]; + + byte[] BYTES_NEW_LINE = StringPool.NEWLINE.getBytes(); +} diff --git a/renren-generator/src/main/java/io/renren/utils/SystemClock.java b/renren-generator/src/main/java/io/renren/utils/SystemClock.java new file mode 100644 index 0000000..6d614a6 --- /dev/null +++ b/renren-generator/src/main/java/io/renren/utils/SystemClock.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011-2020, hubin (jobob@qq.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.renren.utils; + +import java.sql.Timestamp; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +/** + *

+ * 高并发场景下System.currentTimeMillis()的性能问题的优化 + *

+ *

+ * System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我还没测试过,有人说是100倍左右)
+ * System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道
+ * 后台定时更新时钟,JVM退出时,线程自动回收
+ * 10亿:43410,206,210.72815533980582%
+ * 1亿:4699,29,162.0344827586207%
+ * 1000万:480,12,40.0%
+ * 100万:50,10,5.0%
+ *

+ * + * @author hubin + * @since 2016-08-01 + */ +public class SystemClock { + + private final long period; + private final AtomicLong now; + + private SystemClock(long period) { + this.period = period; + this.now = new AtomicLong(System.currentTimeMillis()); + scheduleClockUpdating(); + } + + private static SystemClock instance() { + return InstanceHolder.INSTANCE; + } + + public static long now() { + return instance().currentTimeMillis(); + } + + public static String nowDate() { + return new Timestamp(instance().currentTimeMillis()).toString(); + } + + private void scheduleClockUpdating() { + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(runnable -> { + Thread thread = new Thread(runnable, "System Clock"); + thread.setDaemon(true); + return thread; + }); + scheduler.scheduleAtFixedRate(() -> now.set(System.currentTimeMillis()), period, period, TimeUnit.MILLISECONDS); + } + + private long currentTimeMillis() { + return now.get(); + } + + private static class InstanceHolder { + public static final SystemClock INSTANCE = new SystemClock(1); + } +} diff --git a/renren-generator/src/main/resources/application.yml b/renren-generator/src/main/resources/application.yml new file mode 100644 index 0000000..77792a8 --- /dev/null +++ b/renren-generator/src/main/resources/application.yml @@ -0,0 +1,50 @@ +server: + port: 8082 + servlet: + context-path: /renren-generator + + +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + #MySQL配置 + driverClassName: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/mt_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + username: root + password: zyx007 + #oracle配置 +# driverClassName: oracle.jdbc.OracleDriver +# url: jdbc:oracle:thin:@192.168.10.10:1521:xe +# username: renren_security +# password: 123456 + #SQLServer配置 +# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver +# url: jdbc:sqlserver://192.168.10.10:1433;DatabaseName=renren_security +# username: sa +# password: 123456 + #PostgreSQL配置 +# driverClassName: org.postgresql.Driver +# url: jdbc:postgresql://192.168.10.10:5432/renren_security +# username: postgres +# password: 123456 + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + web: + resources: + static-locations: classpath:/static/,classpath:/views/ + + +mybatis: + mapperLocations: classpath:mapper/**/*.xml + + +pagehelper: + reasonable: true + supportMethodsArguments: true + params: count=countSql + + +#指定数据库,可选值有【mysql、oracle、sqlserver、postgresql】 +renren: + database: mysql \ No newline at end of file diff --git a/renren-generator/src/main/resources/generator.properties b/renren-generator/src/main/resources/generator.properties new file mode 100644 index 0000000..30a3d26 --- /dev/null +++ b/renren-generator/src/main/resources/generator.properties @@ -0,0 +1,68 @@ +#\u4EE3\u7801\u751F\u6210\u5668\uFF0C\u914D\u7F6E\u4FE1\u606F + +#\u5305\u540D +package=io.renren +moduleName=takeout +#\u4F5C\u8005 +author=zyx +#Email +email= +#\u8868\u524D\u7F00(\u7C7B\u540D\u4E0D\u4F1A\u5305\u542B\u8868\u524D\u7F00) +tablePrefix= +version=1.0.0 + + +#\u7C7B\u578B\u8F6C\u6362\uFF0C\u914D\u7F6E\u4FE1\u606F +tinyint=Integer +smallint=Integer +mediumint=Integer +int=Integer +integer=Integer +bigint=Long +float=Float +double=Double +decimal=BigDecimal +bit=Boolean +bool=Boolean + +char=String +varchar=String +tinytext=String +text=String +mediumtext=String +longtext=String + +date=Date +datetime=Date +timestamp=Date + +NUMBER=Integer +INT=Integer +INTEGER=Integer +BINARY_INTEGER=Integer +LONG=String +FLOAT=Float +BINARY_FLOAT=Float +DOUBLE=Double +BINARY_DOUBLE=Double +DECIMAL=BigDecimal +CHAR=String +VARCHAR=String +VARCHAR2=String +NVARCHAR=String +NVARCHAR2=String +CLOB=String +BLOB=String +DATE=Date +DATETIME=Date +TIMESTAMP=Date +TIMESTAMP(6)=Date + +int8=Long +int4=Integer +int2=Integer +numeric=BigDecimal + +INT16=Short +INT32=Integer +INT64=Long diff --git a/renren-generator/src/main/resources/logback-spring.xml b/renren-generator/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..c8b9f41 --- /dev/null +++ b/renren-generator/src/main/resources/logback-spring.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/mapper/MySQLGeneratorDao.xml b/renren-generator/src/main/resources/mapper/MySQLGeneratorDao.xml new file mode 100644 index 0000000..0e9ad8f --- /dev/null +++ b/renren-generator/src/main/resources/mapper/MySQLGeneratorDao.xml @@ -0,0 +1,23 @@ + + + + + + + + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/mapper/OracleGeneratorDao.xml b/renren-generator/src/main/resources/mapper/OracleGeneratorDao.xml new file mode 100644 index 0000000..678843d --- /dev/null +++ b/renren-generator/src/main/resources/mapper/OracleGeneratorDao.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/mapper/PostgreSQLGeneratorDao.xml b/renren-generator/src/main/resources/mapper/PostgreSQLGeneratorDao.xml new file mode 100644 index 0000000..88f6f7c --- /dev/null +++ b/renren-generator/src/main/resources/mapper/PostgreSQLGeneratorDao.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/mapper/SQLServerGeneratorDao.xml b/renren-generator/src/main/resources/mapper/SQLServerGeneratorDao.xml new file mode 100644 index 0000000..f066975 --- /dev/null +++ b/renren-generator/src/main/resources/mapper/SQLServerGeneratorDao.xml @@ -0,0 +1,90 @@ + + + + + + + + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/css/AdminLTE.min.css b/renren-generator/src/main/resources/static/css/AdminLTE.min.css new file mode 100644 index 0000000..8fbee1f --- /dev/null +++ b/renren-generator/src/main/resources/static/css/AdminLTE.min.css @@ -0,0 +1,7 @@ +/*! + * AdminLTE v2.3.7 + * Author: Almsaeed Studio + * Website: Almsaeed Studio + * License: Open source - MIT + * Please visit http://opensource.org/licenses/MIT for more information +!*/html,body{min-height:100%}.layout-boxed html,.layout-boxed body{height:100%}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:400;overflow-x:hidden;overflow-y:auto}.wrapper{min-height:100%;position:relative;overflow:hidden}.wrapper:before,.wrapper:after{content:" ";display:table}.wrapper:after{clear:both}.layout-boxed .wrapper{max-width:1250px;margin:0 auto;min-height:100%;box-shadow:0 0 8px rgba(0,0,0,0.5);position:relative}.layout-boxed{background:url('../img/boxed-bg.jpg') repeat fixed}.content-wrapper,.right-side,.main-footer{-webkit-transition:-webkit-transform .3s ease-in-out,margin .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,margin .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,margin .3s ease-in-out;transition:transform .3s ease-in-out,margin .3s ease-in-out;margin-left:230px;z-index:820}.layout-top-nav .content-wrapper,.layout-top-nav .right-side,.layout-top-nav .main-footer{margin-left:0}@media (max-width:767px){.content-wrapper,.right-side,.main-footer{margin-left:0}}@media (min-width:768px){.sidebar-collapse .content-wrapper,.sidebar-collapse .right-side,.sidebar-collapse .main-footer{margin-left:0}}@media (max-width:767px){.sidebar-open .content-wrapper,.sidebar-open .right-side,.sidebar-open .main-footer{-webkit-transform:translate(230px, 0);-ms-transform:translate(230px, 0);-o-transform:translate(230px, 0);transform:translate(230px, 0)}}.content-wrapper,.right-side{min-height:100%;background-color:#ecf0f5;z-index:800}.main-footer{background:#fff;padding:15px;color:#444;border-top:1px solid #d2d6de}.fixed .main-header,.fixed .main-sidebar,.fixed .left-side{position:fixed}.fixed .main-header{top:0;right:0;left:0}.fixed .content-wrapper,.fixed .right-side{padding-top:50px}@media (max-width:767px){.fixed .content-wrapper,.fixed .right-side{padding-top:100px}}.fixed.layout-boxed .wrapper{max-width:100%}body.hold-transition .content-wrapper,body.hold-transition .right-side,body.hold-transition .main-footer,body.hold-transition .main-sidebar,body.hold-transition .left-side,body.hold-transition .main-header .navbar,body.hold-transition .main-header .logo{-webkit-transition:none;-o-transition:none;transition:none}.content{min-height:250px;padding:15px;margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:'Source Sans Pro',sans-serif}a{color:#3c8dbc}a:hover,a:active,a:focus{outline:none;text-decoration:none;color:#72afd2}.page-header{margin:10px 0 20px 0;font-size:22px}.page-header>small{color:#666;display:block;margin-top:5px}.main-header{position:relative;max-height:100px;z-index:1030}.main-header .navbar{-webkit-transition:margin-left .3s ease-in-out;-o-transition:margin-left .3s ease-in-out;transition:margin-left .3s ease-in-out;margin-bottom:0;margin-left:230px;border:none;min-height:50px;border-radius:0}.layout-top-nav .main-header .navbar{margin-left:0}.main-header #navbar-search-input.form-control{background:rgba(255,255,255,0.2);border-color:transparent}.main-header #navbar-search-input.form-control:focus,.main-header #navbar-search-input.form-control:active{border-color:rgba(0,0,0,0.1);background:rgba(255,255,255,0.9)}.main-header #navbar-search-input.form-control::-moz-placeholder{color:#ccc;opacity:1}.main-header #navbar-search-input.form-control:-ms-input-placeholder{color:#ccc}.main-header #navbar-search-input.form-control::-webkit-input-placeholder{color:#ccc}.main-header .navbar-custom-menu,.main-header .navbar-right{float:right}@media (max-width:991px){.main-header .navbar-custom-menu a,.main-header .navbar-right a{color:inherit;background:transparent}}@media (max-width:767px){.main-header .navbar-right{float:none}.navbar-collapse .main-header .navbar-right{margin:7.5px -15px}.main-header .navbar-right>li{color:inherit;border:0}}.main-header .sidebar-toggle{float:left;background-color:transparent;background-image:none;padding:15px 15px;font-family:fontAwesome}.main-header .sidebar-toggle:before{content:"\f0c9"}.main-header .sidebar-toggle:hover{color:#fff}.main-header .sidebar-toggle:focus,.main-header .sidebar-toggle:active{background:transparent}.main-header .sidebar-toggle .icon-bar{display:none}.main-header .navbar .nav>li.user>a>.fa,.main-header .navbar .nav>li.user>a>.glyphicon,.main-header .navbar .nav>li.user>a>.ion{margin-right:5px}.main-header .navbar .nav>li>a>.label{position:absolute;top:9px;right:7px;text-align:center;font-size:9px;padding:2px 3px;line-height:.9}.main-header .logo{-webkit-transition:width .3s ease-in-out;-o-transition:width .3s ease-in-out;transition:width .3s ease-in-out;display:block;float:left;height:50px;font-size:20px;line-height:50px;text-align:center;width:230px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;padding:0 15px;font-weight:300;overflow:hidden}.main-header .logo .logo-lg{display:block}.main-header .logo .logo-mini{display:none}.main-header .navbar-brand{color:#fff}.content-header{position:relative;padding:15px 15px 0 15px}.content-header>h1{margin:0;font-size:24px}.content-header>h1>small{font-size:15px;display:inline-block;padding-left:4px;font-weight:300}.content-header>.breadcrumb{float:right;background:transparent;margin-top:0;margin-bottom:0;font-size:12px;padding:7px 5px;position:absolute;top:15px;right:10px;border-radius:2px}.content-header>.breadcrumb>li>a{color:#444;text-decoration:none;display:inline-block}.content-header>.breadcrumb>li>a>.fa,.content-header>.breadcrumb>li>a>.glyphicon,.content-header>.breadcrumb>li>a>.ion{margin-right:5px}.content-header>.breadcrumb>li+li:before{content:'>\00a0'}@media (max-width:991px){.content-header>.breadcrumb{position:relative;margin-top:5px;top:0;right:0;float:none;background:#d2d6de;padding-left:10px}.content-header>.breadcrumb li:before{color:#97a0b3}}.navbar-toggle{color:#fff;border:0;margin:0;padding:15px 15px}@media (max-width:991px){.navbar-custom-menu .navbar-nav>li{float:left}.navbar-custom-menu .navbar-nav{margin:0;float:left}.navbar-custom-menu .navbar-nav>li>a{padding-top:15px;padding-bottom:15px;line-height:20px}}@media (max-width:767px){.main-header{position:relative}.main-header .logo,.main-header .navbar{width:100%;float:none}.main-header .navbar{margin:0}.main-header .navbar-custom-menu{float:right}}@media (max-width:991px){.navbar-collapse.pull-left{float:none !important}.navbar-collapse.pull-left+.navbar-custom-menu{display:block;position:absolute;top:0;right:40px}}.main-sidebar,.left-side{position:absolute;top:0;left:0;padding-top:50px;min-height:100%;width:230px;z-index:810;-webkit-transition:-webkit-transform .3s ease-in-out,width .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,width .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,width .3s ease-in-out;transition:transform .3s ease-in-out,width .3s ease-in-out}@media (max-width:767px){.main-sidebar,.left-side{padding-top:100px}}@media (max-width:767px){.main-sidebar,.left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (min-width:768px){.sidebar-collapse .main-sidebar,.sidebar-collapse .left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (max-width:767px){.sidebar-open .main-sidebar,.sidebar-open .left-side{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}}.sidebar{padding-bottom:10px}.sidebar-form input:focus{border-color:transparent}.user-panel{position:relative;width:100%;padding:10px;overflow:hidden}.user-panel:before,.user-panel:after{content:" ";display:table}.user-panel:after{clear:both}.user-panel>.image>img{width:100%;max-width:45px;height:auto}.user-panel>.info{padding:5px 5px 5px 15px;line-height:1;position:absolute;left:55px}.user-panel>.info>p{font-weight:600;margin-bottom:9px}.user-panel>.info>a{text-decoration:none;padding-right:5px;margin-top:3px;font-size:11px}.user-panel>.info>a>.fa,.user-panel>.info>a>.ion,.user-panel>.info>a>.glyphicon{margin-right:3px}.sidebar-menu{list-style:none;margin:0;padding:0}.sidebar-menu>li{position:relative;margin:0;padding:0}.sidebar-menu>li>a{padding:12px 5px 12px 15px;display:block}.sidebar-menu>li>a>.fa,.sidebar-menu>li>a>.glyphicon,.sidebar-menu>li>a>.ion{width:20px}.sidebar-menu>li .label,.sidebar-menu>li .badge{margin-right:5px}.sidebar-menu>li .badge{margin-top:3px}.sidebar-menu li.header{padding:10px 25px 10px 15px;font-size:12px}.sidebar-menu li>a>.fa-angle-left,.sidebar-menu li>a>.pull-right-container>.fa-angle-left{width:auto;height:auto;padding:0;margin-right:10px}.sidebar-menu li.active>a>.fa-angle-left,.sidebar-menu li.active>a>.pull-right-container>.fa-angle-left{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.sidebar-menu li.active>.treeview-menu{display:block}.sidebar-menu .treeview-menu{display:none;list-style:none;padding:0;margin:0;padding-left:5px}.sidebar-menu .treeview-menu .treeview-menu{padding-left:20px}.sidebar-menu .treeview-menu>li{margin:0}.sidebar-menu .treeview-menu>li>a{padding:5px 5px 5px 15px;display:block;font-size:14px}.sidebar-menu .treeview-menu>li>a>.fa,.sidebar-menu .treeview-menu>li>a>.glyphicon,.sidebar-menu .treeview-menu>li>a>.ion{width:20px}.sidebar-menu .treeview-menu>li>a>.pull-right-container>.fa-angle-left,.sidebar-menu .treeview-menu>li>a>.pull-right-container>.fa-angle-down,.sidebar-menu .treeview-menu>li>a>.fa-angle-left,.sidebar-menu .treeview-menu>li>a>.fa-angle-down{width:auto}@media (min-width:768px){.sidebar-mini.sidebar-collapse .content-wrapper,.sidebar-mini.sidebar-collapse .right-side,.sidebar-mini.sidebar-collapse .main-footer{margin-left:50px !important;z-index:840}.sidebar-mini.sidebar-collapse .main-sidebar{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);width:50px !important;z-index:850}.sidebar-mini.sidebar-collapse .sidebar-menu>li{position:relative}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a{margin-right:0}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span{border-top-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:not(.treeview)>a>span{border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{padding-top:5px;padding-bottom:5px;border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span:not(.pull-right),.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{display:block !important;position:absolute;width:180px;left:50px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span{top:0;margin-left:-3px;padding:12px 5px 12px 20px;background-color:inherit}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>.pull-right-container{float:right;width:auto!important;left:200px!important;top:10px!important}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>.pull-right-container>.label:not(:first-of-type){display:none}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{top:44px;margin-left:0}.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.info,.sidebar-mini.sidebar-collapse .sidebar-form,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span,.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>.pull-right,.sidebar-mini.sidebar-collapse .sidebar-menu li.header{display:none !important;-webkit-transform:translateZ(0)}.sidebar-mini.sidebar-collapse .main-header .logo{width:50px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-mini{display:block;margin-left:-15px;margin-right:-15px;font-size:18px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-lg{display:none}.sidebar-mini.sidebar-collapse .main-header .navbar{margin-left:50px}}.sidebar-menu,.main-sidebar .user-panel,.sidebar-menu>li.header{white-space:nowrap;overflow:hidden}.sidebar-menu:hover{overflow:visible}.sidebar-form,.sidebar-menu>li.header{overflow:hidden;text-overflow:clip}.sidebar-menu li>a{position:relative}.sidebar-menu li>a>.pull-right-container{position:absolute;right:10px;top:50%;margin-top:-7px}.control-sidebar-bg{position:fixed;z-index:1000;bottom:0}.control-sidebar-bg,.control-sidebar{top:0;right:-230px;width:230px;-webkit-transition:right .3s ease-in-out;-o-transition:right .3s ease-in-out;transition:right .3s ease-in-out}.control-sidebar{position:absolute;padding-top:50px;z-index:1010}@media (max-width:768px){.control-sidebar{padding-top:100px}}.control-sidebar>.tab-content{padding:10px 15px}.control-sidebar.control-sidebar-open,.control-sidebar.control-sidebar-open+.control-sidebar-bg{right:0}.control-sidebar-open .control-sidebar-bg,.control-sidebar-open .control-sidebar{right:0}@media (min-width:768px){.control-sidebar-open .content-wrapper,.control-sidebar-open .right-side,.control-sidebar-open .main-footer{margin-right:230px}}.nav-tabs.control-sidebar-tabs>li:first-of-type>a,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:hover,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:focus{border-left-width:0}.nav-tabs.control-sidebar-tabs>li>a{border-radius:0}.nav-tabs.control-sidebar-tabs>li>a,.nav-tabs.control-sidebar-tabs>li>a:hover{border-top:none;border-right:none;border-left:1px solid transparent;border-bottom:1px solid transparent}.nav-tabs.control-sidebar-tabs>li>a .icon{font-size:16px}.nav-tabs.control-sidebar-tabs>li.active>a,.nav-tabs.control-sidebar-tabs>li.active>a:hover,.nav-tabs.control-sidebar-tabs>li.active>a:focus,.nav-tabs.control-sidebar-tabs>li.active>a:active{border-top:none;border-right:none;border-bottom:none}@media (max-width:768px){.nav-tabs.control-sidebar-tabs{display:table}.nav-tabs.control-sidebar-tabs>li{display:table-cell}}.control-sidebar-heading{font-weight:400;font-size:16px;padding:10px 0;margin-bottom:10px}.control-sidebar-subheading{display:block;font-weight:400;font-size:14px}.control-sidebar-menu{list-style:none;padding:0;margin:0 -15px}.control-sidebar-menu>li>a{display:block;padding:10px 15px}.control-sidebar-menu>li>a:before,.control-sidebar-menu>li>a:after{content:" ";display:table}.control-sidebar-menu>li>a:after{clear:both}.control-sidebar-menu>li>a>.control-sidebar-subheading{margin-top:0}.control-sidebar-menu .menu-icon{float:left;width:35px;height:35px;border-radius:50%;text-align:center;line-height:35px}.control-sidebar-menu .menu-info{margin-left:45px;margin-top:3px}.control-sidebar-menu .menu-info>.control-sidebar-subheading{margin:0}.control-sidebar-menu .menu-info>p{margin:0;font-size:11px}.control-sidebar-menu .progress{margin:0}.control-sidebar-dark{color:#b8c7ce}.control-sidebar-dark,.control-sidebar-dark+.control-sidebar-bg{background:#222d32}.control-sidebar-dark .nav-tabs.control-sidebar-tabs{border-bottom:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a{background:#181f23;color:#b8c7ce}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#141a1d;border-bottom-color:#141a1d}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:active{background:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover{color:#fff}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#222d32;color:#fff}.control-sidebar-dark .control-sidebar-heading,.control-sidebar-dark .control-sidebar-subheading{color:#fff}.control-sidebar-dark .control-sidebar-menu>li>a:hover{background:#1e282c}.control-sidebar-dark .control-sidebar-menu>li>a .menu-info>p{color:#b8c7ce}.control-sidebar-light{color:#5e5e5e}.control-sidebar-light,.control-sidebar-light+.control-sidebar-bg{background:#f9fafc;border-left:1px solid #d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs{border-bottom:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a{background:#e8ecf4;color:#444}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#d2d6de;border-bottom-color:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:active{background:#eff1f7}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#f9fafc;color:#111}.control-sidebar-light .control-sidebar-heading,.control-sidebar-light .control-sidebar-subheading{color:#111}.control-sidebar-light .control-sidebar-menu{margin-left:-14px}.control-sidebar-light .control-sidebar-menu>li>a:hover{background:#f4f4f5}.control-sidebar-light .control-sidebar-menu>li>a .menu-info>p{color:#5e5e5e}.dropdown-menu{box-shadow:none;border-color:#eee}.dropdown-menu>li>a{color:#777}.dropdown-menu>li>a>.glyphicon,.dropdown-menu>li>a>.fa,.dropdown-menu>li>a>.ion{margin-right:10px}.dropdown-menu>li>a:hover{background-color:#e1e3e9;color:#333}.dropdown-menu>.divider{background-color:#eee}.navbar-nav>.notifications-menu>.dropdown-menu,.navbar-nav>.messages-menu>.dropdown-menu,.navbar-nav>.tasks-menu>.dropdown-menu{width:280px;padding:0 0 0 0;margin:0;top:100%}.navbar-nav>.notifications-menu>.dropdown-menu>li,.navbar-nav>.messages-menu>.dropdown-menu>li,.navbar-nav>.tasks-menu>.dropdown-menu>li{position:relative}.navbar-nav>.notifications-menu>.dropdown-menu>li.header,.navbar-nav>.messages-menu>.dropdown-menu>li.header,.navbar-nav>.tasks-menu>.dropdown-menu>li.header{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:#ffffff;padding:7px 10px;border-bottom:1px solid #f4f4f4;color:#444444;font-size:14px}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px;font-size:12px;background-color:#fff;padding:7px 10px;border-bottom:1px solid #eeeeee;color:#444 !important;text-align:center}@media (max-width:991px){.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{background:#fff !important;color:#444 !important}}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a:hover{text-decoration:none;font-weight:normal}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu,.navbar-nav>.messages-menu>.dropdown-menu>li .menu,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu{max-height:200px;margin:0;padding:0;list-style:none;overflow-x:hidden}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{display:block;white-space:nowrap;border-bottom:1px solid #f4f4f4}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a:hover{background:#f4f4f4;text-decoration:none}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a{color:#444444;overflow:hidden;text-overflow:ellipsis;padding:10px}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.glyphicon,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.fa,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.ion{width:20px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a{margin:0;padding:10px 10px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>div>img{margin:auto 10px auto auto;width:40px;height:40px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4{padding:0;margin:0 0 0 45px;color:#444444;font-size:15px;position:relative}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4>small{color:#999999;font-size:10px;position:absolute;top:0;right:0}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>p{margin:0 0 0 45px;font-size:12px;color:#888888}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:before,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{content:" ";display:table}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{clear:both}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{padding:10px}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>h3{font-size:14px;padding:0;margin:0 0 10px 0;color:#666666}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>.progress{padding:0;margin:0}.navbar-nav>.user-menu>.dropdown-menu{border-top-right-radius:0;border-top-left-radius:0;padding:1px 0 0 0;border-top-width:0;width:280px}.navbar-nav>.user-menu>.dropdown-menu,.navbar-nav>.user-menu>.dropdown-menu>.user-body{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header{height:175px;padding:10px;text-align:center}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>img{z-index:5;height:90px;width:90px;border:3px solid;border-color:transparent;border-color:rgba(255,255,255,0.2)}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p{z-index:5;color:#fff;color:rgba(255,255,255,0.8);font-size:17px;margin-top:10px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p>small{display:block;font-size:12px}.navbar-nav>.user-menu>.dropdown-menu>.user-body{padding:15px;border-bottom:1px solid #f4f4f4;border-top:1px solid #dddddd}.navbar-nav>.user-menu>.dropdown-menu>.user-body:before,.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-body a{color:#444 !important}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-body a{background:#fff !important;color:#444 !important}}.navbar-nav>.user-menu>.dropdown-menu>.user-footer{background-color:#f9f9f9;padding:10px}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:before,.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default{color:#666666}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default:hover{background-color:#f9f9f9}}.navbar-nav>.user-menu .user-image{float:left;width:25px;height:25px;border-radius:50%;margin-right:10px;margin-top:-2px}@media (max-width:767px){.navbar-nav>.user-menu .user-image{float:none;margin-right:0;margin-top:-8px;line-height:10px}}.open:not(.dropup)>.animated-dropdown-menu{backface-visibility:visible !important;-webkit-animation:flipInX .7s both;-o-animation:flipInX .7s both;animation:flipInX .7s both}@keyframes flipInX{0%{transform:perspective(400px) rotate3d(1, 0, 0, 90deg);transition-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotate3d(1, 0, 0, -20deg);transition-timing-function:ease-in}60%{transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{transform:perspective(400px)}}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 90deg);-webkit-transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -20deg);-webkit-transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{-webkit-transform:perspective(400px)}}.navbar-custom-menu>.navbar-nav>li{position:relative}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:0;left:auto}@media (max-width:991px){.navbar-custom-menu>.navbar-nav{float:right}.navbar-custom-menu>.navbar-nav>li{position:static}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:5%;left:auto;border:1px solid #ddd;background:#fff}}.form-control{border-radius:0;box-shadow:none;border-color:#d2d6de}.form-control:focus{border-color:#3c8dbc;box-shadow:none}.form-control::-moz-placeholder,.form-control:-ms-input-placeholder,.form-control::-webkit-input-placeholder{color:#bbb;opacity:1}.form-control:not(select){-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-group.has-success label{color:#00a65a}.form-group.has-success .form-control,.form-group.has-success .input-group-addon{border-color:#00a65a;box-shadow:none}.form-group.has-success .help-block{color:#00a65a}.form-group.has-warning label{color:#f39c12}.form-group.has-warning .form-control,.form-group.has-warning .input-group-addon{border-color:#f39c12;box-shadow:none}.form-group.has-warning .help-block{color:#f39c12}.form-group.has-error label{color:#dd4b39}.form-group.has-error .form-control,.form-group.has-error .input-group-addon{border-color:#dd4b39;box-shadow:none}.form-group.has-error .help-block{color:#dd4b39}.input-group .input-group-addon{border-radius:0;border-color:#d2d6de;background-color:#fff}.btn-group-vertical .btn.btn-flat:first-of-type,.btn-group-vertical .btn.btn-flat:last-of-type{border-radius:0}.icheck>label{padding-left:0}.form-control-feedback.fa{line-height:34px}.input-lg+.form-control-feedback.fa,.input-group-lg+.form-control-feedback.fa,.form-group-lg .form-control+.form-control-feedback.fa{line-height:46px}.input-sm+.form-control-feedback.fa,.input-group-sm+.form-control-feedback.fa,.form-group-sm .form-control+.form-control-feedback.fa{line-height:30px}.progress,.progress>.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress,.progress>.progress-bar,.progress .progress-bar,.progress>.progress-bar .progress-bar{border-radius:1px}.progress.sm,.progress-sm{height:10px}.progress.sm,.progress-sm,.progress.sm .progress-bar,.progress-sm .progress-bar{border-radius:1px}.progress.xs,.progress-xs{height:7px}.progress.xs,.progress-xs,.progress.xs .progress-bar,.progress-xs .progress-bar{border-radius:1px}.progress.xxs,.progress-xxs{height:3px}.progress.xxs,.progress-xxs,.progress.xxs .progress-bar,.progress-xxs .progress-bar{border-radius:1px}.progress.vertical{position:relative;width:30px;height:200px;display:inline-block;margin-right:10px}.progress.vertical>.progress-bar{width:100%;position:absolute;bottom:0}.progress.vertical.sm,.progress.vertical.progress-sm{width:20px}.progress.vertical.xs,.progress.vertical.progress-xs{width:10px}.progress.vertical.xxs,.progress.vertical.progress-xxs{width:3px}.progress-group .progress-text{font-weight:600}.progress-group .progress-number{float:right}.table tr>td .progress{margin:0}.progress-bar-light-blue,.progress-bar-primary{background-color:#3c8dbc}.progress-striped .progress-bar-light-blue,.progress-striped .progress-bar-primary{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-green,.progress-bar-success{background-color:#00a65a}.progress-striped .progress-bar-green,.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-aqua,.progress-bar-info{background-color:#00c0ef}.progress-striped .progress-bar-aqua,.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-yellow,.progress-bar-warning{background-color:#f39c12}.progress-striped .progress-bar-yellow,.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-red,.progress-bar-danger{background-color:#dd4b39}.progress-striped .progress-bar-red,.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.small-box{border-radius:2px;position:relative;display:block;margin-bottom:20px;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.small-box>.inner{padding:10px}.small-box>.small-box-footer{position:relative;text-align:center;padding:3px 0;color:#fff;color:rgba(255,255,255,0.8);display:block;z-index:10;background:rgba(0,0,0,0.1);text-decoration:none}.small-box>.small-box-footer:hover{color:#fff;background:rgba(0,0,0,0.15)}.small-box h3{font-size:38px;font-weight:bold;margin:0 0 10px 0;white-space:nowrap;padding:0}.small-box p{font-size:15px}.small-box p>small{display:block;color:#f9f9f9;font-size:13px;margin-top:5px}.small-box h3,.small-box p{z-index:5}.small-box .icon{-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;position:absolute;top:-10px;right:10px;z-index:0;font-size:90px;color:rgba(0,0,0,0.15)}.small-box:hover{text-decoration:none;color:#f9f9f9}.small-box:hover .icon{font-size:95px}@media (max-width:767px){.small-box{text-align:center}.small-box .icon{display:none}.small-box p{font-size:12px}}.box{position:relative;border-radius:3px;background:#ffffff;border-top:3px solid #d2d6de;margin-bottom:20px;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.box.box-primary{border-top-color:#3c8dbc}.box.box-info{border-top-color:#00c0ef}.box.box-danger{border-top-color:#dd4b39}.box.box-warning{border-top-color:#f39c12}.box.box-success{border-top-color:#00a65a}.box.box-default{border-top-color:#d2d6de}.box.collapsed-box .box-body,.box.collapsed-box .box-footer{display:none}.box .nav-stacked>li{border-bottom:1px solid #f4f4f4;margin:0}.box .nav-stacked>li:last-of-type{border-bottom:none}.box.height-control .box-body{max-height:300px;overflow:auto}.box .border-right{border-right:1px solid #f4f4f4}.box .border-left{border-left:1px solid #f4f4f4}.box.box-solid{border-top:0}.box.box-solid>.box-header .btn.btn-default{background:transparent}.box.box-solid>.box-header .btn:hover,.box.box-solid>.box-header a:hover{background:rgba(0,0,0,0.1)}.box.box-solid.box-default{border:1px solid #d2d6de}.box.box-solid.box-default>.box-header{color:#444;background:#d2d6de;background-color:#d2d6de}.box.box-solid.box-default>.box-header a,.box.box-solid.box-default>.box-header .btn{color:#444}.box.box-solid.box-primary{border:1px solid #3c8dbc}.box.box-solid.box-primary>.box-header{color:#fff;background:#3c8dbc;background-color:#3c8dbc}.box.box-solid.box-primary>.box-header a,.box.box-solid.box-primary>.box-header .btn{color:#fff}.box.box-solid.box-info{border:1px solid #00c0ef}.box.box-solid.box-info>.box-header{color:#fff;background:#00c0ef;background-color:#00c0ef}.box.box-solid.box-info>.box-header a,.box.box-solid.box-info>.box-header .btn{color:#fff}.box.box-solid.box-danger{border:1px solid #dd4b39}.box.box-solid.box-danger>.box-header{color:#fff;background:#dd4b39;background-color:#dd4b39}.box.box-solid.box-danger>.box-header a,.box.box-solid.box-danger>.box-header .btn{color:#fff}.box.box-solid.box-warning{border:1px solid #f39c12}.box.box-solid.box-warning>.box-header{color:#fff;background:#f39c12;background-color:#f39c12}.box.box-solid.box-warning>.box-header a,.box.box-solid.box-warning>.box-header .btn{color:#fff}.box.box-solid.box-success{border:1px solid #00a65a}.box.box-solid.box-success>.box-header{color:#fff;background:#00a65a;background-color:#00a65a}.box.box-solid.box-success>.box-header a,.box.box-solid.box-success>.box-header .btn{color:#fff}.box.box-solid>.box-header>.box-tools .btn{border:0;box-shadow:none}.box.box-solid[class*='bg']>.box-header{color:#fff}.box .box-group>.box{margin-bottom:5px}.box .knob-label{text-align:center;color:#333;font-weight:100;font-size:12px;margin-bottom:0.3em}.box>.overlay,.overlay-wrapper>.overlay,.box>.loading-img,.overlay-wrapper>.loading-img{position:absolute;top:0;left:0;width:100%;height:100%}.box .overlay,.overlay-wrapper .overlay{z-index:50;background:rgba(255,255,255,0.7);border-radius:3px}.box .overlay>.fa,.overlay-wrapper .overlay>.fa{position:absolute;top:50%;left:50%;margin-left:-15px;margin-top:-15px;color:#000;font-size:30px}.box .overlay.dark,.overlay-wrapper .overlay.dark{background:rgba(0,0,0,0.5)}.box-header:before,.box-body:before,.box-footer:before,.box-header:after,.box-body:after,.box-footer:after{content:" ";display:table}.box-header:after,.box-body:after,.box-footer:after{clear:both}.box-header{color:#444;display:block;padding:10px;position:relative}.box-header.with-border{border-bottom:1px solid #f4f4f4}.collapsed-box .box-header.with-border{border-bottom:none}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion,.box-header .box-title{display:inline-block;font-size:18px;margin:0;line-height:1}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion{margin-right:5px}.box-header>.box-tools{position:absolute;right:10px;top:5px}.box-header>.box-tools [data-toggle="tooltip"]{position:relative}.box-header>.box-tools.pull-right .dropdown-menu{right:0;left:auto}.btn-box-tool{padding:5px;font-size:12px;background:transparent;color:#97a0b3}.open .btn-box-tool,.btn-box-tool:hover{color:#606c84}.btn-box-tool.btn:active{box-shadow:none}.box-body{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;padding:10px}.no-header .box-body{border-top-right-radius:3px;border-top-left-radius:3px}.box-body>.table{margin-bottom:0}.box-body .fc{margin-top:5px}.box-body .full-width-chart{margin:-19px}.box-body.no-padding .full-width-chart{margin:-9px}.box-body .box-pane{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:3px}.box-body .box-pane-right{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:0}.box-footer{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top:1px solid #f4f4f4;padding:10px;background-color:#fff}.chart-legend{margin:10px 0}@media (max-width:991px){.chart-legend>li{float:left;margin-right:10px}}.box-comments{background:#f7f7f7}.box-comments .box-comment{padding:8px 0;border-bottom:1px solid #eee}.box-comments .box-comment:before,.box-comments .box-comment:after{content:" ";display:table}.box-comments .box-comment:after{clear:both}.box-comments .box-comment:last-of-type{border-bottom:0}.box-comments .box-comment:first-of-type{padding-top:0}.box-comments .box-comment img{float:left}.box-comments .comment-text{margin-left:40px;color:#555}.box-comments .username{color:#444;display:block;font-weight:600}.box-comments .text-muted{font-weight:400;font-size:12px}.todo-list{margin:0;padding:0;list-style:none;overflow:auto}.todo-list>li{border-radius:2px;padding:10px;background:#f4f4f4;margin-bottom:2px;border-left:2px solid #e6e7e8;color:#444}.todo-list>li:last-of-type{margin-bottom:0}.todo-list>li>input[type='checkbox']{margin:0 10px 0 5px}.todo-list>li .text{display:inline-block;margin-left:5px;font-weight:600}.todo-list>li .label{margin-left:10px;font-size:9px}.todo-list>li .tools{display:none;float:right;color:#dd4b39}.todo-list>li .tools>.fa,.todo-list>li .tools>.glyphicon,.todo-list>li .tools>.ion{margin-right:5px;cursor:pointer}.todo-list>li:hover .tools{display:inline-block}.todo-list>li.done{color:#999}.todo-list>li.done .text{text-decoration:line-through;font-weight:500}.todo-list>li.done .label{background:#d2d6de !important}.todo-list .danger{border-left-color:#dd4b39}.todo-list .warning{border-left-color:#f39c12}.todo-list .info{border-left-color:#00c0ef}.todo-list .success{border-left-color:#00a65a}.todo-list .primary{border-left-color:#3c8dbc}.todo-list .handle{display:inline-block;cursor:move;margin:0 5px}.chat{padding:5px 20px 5px 10px}.chat .item{margin-bottom:10px}.chat .item:before,.chat .item:after{content:" ";display:table}.chat .item:after{clear:both}.chat .item>img{width:40px;height:40px;border:2px solid transparent;border-radius:50%}.chat .item>.online{border:2px solid #00a65a}.chat .item>.offline{border:2px solid #dd4b39}.chat .item>.message{margin-left:55px;margin-top:-40px}.chat .item>.message>.name{display:block;font-weight:600}.chat .item>.attachment{border-radius:3px;background:#f4f4f4;margin-left:65px;margin-right:15px;padding:10px}.chat .item>.attachment>h4{margin:0 0 5px 0;font-weight:600;font-size:14px}.chat .item>.attachment>p,.chat .item>.attachment>.filename{font-weight:600;font-size:13px;font-style:italic;margin:0}.chat .item>.attachment:before,.chat .item>.attachment:after{content:" ";display:table}.chat .item>.attachment:after{clear:both}.box-input{max-width:200px}.modal .panel-body{color:#444}.info-box{display:block;min-height:90px;background:#fff;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:2px;margin-bottom:15px}.info-box small{font-size:14px}.info-box .progress{background:rgba(0,0,0,0.2);margin:5px -10px 5px -10px;height:2px}.info-box .progress,.info-box .progress .progress-bar{border-radius:0}.info-box .progress .progress-bar{background:#fff}.info-box-icon{border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px;display:block;float:left;height:90px;width:90px;text-align:center;font-size:45px;line-height:90px;background:rgba(0,0,0,0.2)}.info-box-icon>img{max-width:100%}.info-box-content{padding:5px 10px;margin-left:90px}.info-box-number{display:block;font-weight:bold;font-size:18px}.progress-description,.info-box-text{display:block;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.info-box-text{text-transform:uppercase}.info-box-more{display:block}.progress-description{margin:0}.timeline{position:relative;margin:0 0 30px 0;padding:0;list-style:none}.timeline:before{content:'';position:absolute;top:0;bottom:0;width:4px;background:#ddd;left:31px;margin:0;border-radius:2px}.timeline>li{position:relative;margin-right:10px;margin-bottom:15px}.timeline>li:before,.timeline>li:after{content:" ";display:table}.timeline>li:after{clear:both}.timeline>li>.timeline-item{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;margin-top:0;background:#fff;color:#444;margin-left:60px;margin-right:15px;padding:0;position:relative}.timeline>li>.timeline-item>.time{color:#999;float:right;padding:10px;font-size:12px}.timeline>li>.timeline-item>.timeline-header{margin:0;color:#555;border-bottom:1px solid #f4f4f4;padding:10px;font-size:16px;line-height:1.1}.timeline>li>.timeline-item>.timeline-header>a{font-weight:600}.timeline>li>.timeline-item>.timeline-body,.timeline>li>.timeline-item>.timeline-footer{padding:10px}.timeline>li>.fa,.timeline>li>.glyphicon,.timeline>li>.ion{width:30px;height:30px;font-size:15px;line-height:30px;position:absolute;color:#666;background:#d2d6de;border-radius:50%;text-align:center;left:18px;top:0}.timeline>.time-label>span{font-weight:600;padding:5px;display:inline-block;background-color:#fff;border-radius:4px}.timeline-inverse>li>.timeline-item{background:#f0f0f0;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none}.timeline-inverse>li>.timeline-item>.timeline-header{border-bottom-color:#ddd}.btn{border-radius:3px;-webkit-box-shadow:none;box-shadow:none;border:1px solid transparent}.btn.uppercase{text-transform:uppercase}.btn.btn-flat{border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border-width:1px}.btn:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:focus{outline:none}.btn.btn-file{position:relative;overflow:hidden}.btn.btn-file>input[type='file']{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;opacity:0;filter:alpha(opacity=0);outline:none;background:white;cursor:inherit;display:block}.btn-default{background-color:#f4f4f4;color:#444;border-color:#ddd}.btn-default:hover,.btn-default:active,.btn-default.hover{background-color:#e7e7e7}.btn-primary{background-color:#3c8dbc;border-color:#367fa9}.btn-primary:hover,.btn-primary:active,.btn-primary.hover{background-color:#367fa9}.btn-success{background-color:#00a65a;border-color:#008d4c}.btn-success:hover,.btn-success:active,.btn-success.hover{background-color:#008d4c}.btn-info{background-color:#00c0ef;border-color:#00acd6}.btn-info:hover,.btn-info:active,.btn-info.hover{background-color:#00acd6}.btn-danger{background-color:#dd4b39;border-color:#d73925}.btn-danger:hover,.btn-danger:active,.btn-danger.hover{background-color:#d73925}.btn-warning{background-color:#f39c12;border-color:#e08e0b}.btn-warning:hover,.btn-warning:active,.btn-warning.hover{background-color:#e08e0b}.btn-outline{border:1px solid #fff;background:transparent;color:#fff}.btn-outline:hover,.btn-outline:focus,.btn-outline:active{color:rgba(255,255,255,0.7);border-color:rgba(255,255,255,0.7)}.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn[class*='bg-']:hover{-webkit-box-shadow:inset 0 0 100px rgba(0,0,0,0.2);box-shadow:inset 0 0 100px rgba(0,0,0,0.2)}.btn-app{border-radius:3px;position:relative;padding:15px 5px;margin:0 0 10px 10px;min-width:80px;height:60px;text-align:center;color:#666;border:1px solid #ddd;background-color:#f4f4f4;font-size:12px}.btn-app>.fa,.btn-app>.glyphicon,.btn-app>.ion{font-size:20px;display:block}.btn-app:hover{background:#f4f4f4;color:#444;border-color:#aaa}.btn-app:active,.btn-app:focus{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-app>.badge{position:absolute;top:-3px;right:-10px;font-size:10px;font-weight:400}.callout{border-radius:3px;margin:0 0 20px 0;padding:15px 30px 15px 15px;border-left:5px solid #eee}.callout a{color:#fff;text-decoration:underline}.callout a:hover{color:#eee}.callout h4{margin-top:0;font-weight:600}.callout p:last-child{margin-bottom:0}.callout code,.callout .highlight{background-color:#fff}.callout.callout-danger{border-color:#c23321}.callout.callout-warning{border-color:#c87f0a}.callout.callout-info{border-color:#0097bc}.callout.callout-success{border-color:#00733e}.alert{border-radius:3px}.alert h4{font-weight:600}.alert .icon{margin-right:10px}.alert .close{color:#000;opacity:.2;filter:alpha(opacity=20)}.alert .close:hover{opacity:.5;filter:alpha(opacity=50)}.alert a{color:#fff;text-decoration:underline}.alert-success{border-color:#008d4c}.alert-danger,.alert-error{border-color:#d73925}.alert-warning{border-color:#e08e0b}.alert-info{border-color:#00acd6}.nav>li>a:hover,.nav>li>a:active,.nav>li>a:focus{color:#444;background:#f7f7f7}.nav-pills>li>a{border-radius:0;border-top:3px solid transparent;color:#444}.nav-pills>li>a>.fa,.nav-pills>li>a>.glyphicon,.nav-pills>li>a>.ion{margin-right:5px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{border-top-color:#3c8dbc}.nav-pills>li.active>a{font-weight:600}.nav-stacked>li>a{border-radius:0;border-top:0;border-left:3px solid transparent;color:#444}.nav-stacked>li.active>a,.nav-stacked>li.active>a:hover{background:transparent;color:#444;border-top:0;border-left-color:#3c8dbc}.nav-stacked>li.header{border-bottom:1px solid #ddd;color:#777;margin-bottom:10px;padding:5px 10px;text-transform:uppercase}.nav-tabs-custom{margin-bottom:20px;background:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px}.nav-tabs-custom>.nav-tabs{margin:0;border-bottom-color:#f4f4f4;border-top-right-radius:3px;border-top-left-radius:3px}.nav-tabs-custom>.nav-tabs>li{border-top:3px solid transparent;margin-bottom:-2px;margin-right:5px}.nav-tabs-custom>.nav-tabs>li>a{color:#444;border-radius:0}.nav-tabs-custom>.nav-tabs>li>a.text-muted{color:#999}.nav-tabs-custom>.nav-tabs>li>a,.nav-tabs-custom>.nav-tabs>li>a:hover{background:transparent;margin:0}.nav-tabs-custom>.nav-tabs>li>a:hover{color:#999}.nav-tabs-custom>.nav-tabs>li:not(.active)>a:hover,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:focus,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:active{border-color:transparent}.nav-tabs-custom>.nav-tabs>li.active{border-top-color:#3c8dbc}.nav-tabs-custom>.nav-tabs>li.active>a,.nav-tabs-custom>.nav-tabs>li.active:hover>a{background-color:#fff;color:#444}.nav-tabs-custom>.nav-tabs>li.active>a{border-top-color:transparent;border-left-color:#f4f4f4;border-right-color:#f4f4f4}.nav-tabs-custom>.nav-tabs>li:first-of-type{margin-left:0}.nav-tabs-custom>.nav-tabs>li:first-of-type.active>a{border-left-color:transparent}.nav-tabs-custom>.nav-tabs.pull-right{float:none !important}.nav-tabs-custom>.nav-tabs.pull-right>li{float:right}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type{margin-right:0}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type>a{border-left-width:1px}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type.active>a{border-left-color:#f4f4f4;border-right-color:transparent}.nav-tabs-custom>.nav-tabs>li.header{line-height:35px;padding:0 10px;font-size:20px;color:#444}.nav-tabs-custom>.nav-tabs>li.header>.fa,.nav-tabs-custom>.nav-tabs>li.header>.glyphicon,.nav-tabs-custom>.nav-tabs>li.header>.ion{margin-right:5px}.nav-tabs-custom>.tab-content{background:#fff;padding:10px;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.nav-tabs-custom .dropdown.open>a:active,.nav-tabs-custom .dropdown.open>a:focus{background:transparent;color:#999}.nav-tabs-custom.tab-primary>.nav-tabs>li.active{border-top-color:#3c8dbc}.nav-tabs-custom.tab-info>.nav-tabs>li.active{border-top-color:#00c0ef}.nav-tabs-custom.tab-danger>.nav-tabs>li.active{border-top-color:#dd4b39}.nav-tabs-custom.tab-warning>.nav-tabs>li.active{border-top-color:#f39c12}.nav-tabs-custom.tab-success>.nav-tabs>li.active{border-top-color:#00a65a}.nav-tabs-custom.tab-default>.nav-tabs>li.active{border-top-color:#d2d6de}.pagination>li>a{background:#fafafa;color:#666}.pagination.pagination-flat>li>a{border-radius:0 !important}.products-list{list-style:none;margin:0;padding:0}.products-list>.item{border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);padding:10px 0;background:#fff}.products-list>.item:before,.products-list>.item:after{content:" ";display:table}.products-list>.item:after{clear:both}.products-list .product-img{float:left}.products-list .product-img img{width:50px;height:50px}.products-list .product-info{margin-left:60px}.products-list .product-title{font-weight:600}.products-list .product-description{display:block;color:#999;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.product-list-in-box>.item{-webkit-box-shadow:none;box-shadow:none;border-radius:0;border-bottom:1px solid #f4f4f4}.product-list-in-box>.item:last-of-type{border-bottom-width:0}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{border-top:1px solid #f4f4f4}.table>thead>tr>th{border-bottom:2px solid #f4f4f4}.table tr td .progress{margin-top:5px}.table-bordered{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table.no-border,.table.no-border td,.table.no-border th{border:0}table.text-center,table.text-center td,table.text-center th{text-align:center}.table.align th{text-align:left}.table.align td{text-align:right}.label-default{background-color:#d2d6de;color:#444}.direct-chat .box-body{border-bottom-right-radius:0;border-bottom-left-radius:0;position:relative;overflow-x:hidden;padding:0}.direct-chat.chat-pane-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-messages{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);padding:10px;height:250px;overflow:auto}.direct-chat-msg,.direct-chat-text{display:block}.direct-chat-msg{margin-bottom:10px}.direct-chat-msg:before,.direct-chat-msg:after{content:" ";display:table}.direct-chat-msg:after{clear:both}.direct-chat-messages,.direct-chat-contacts{-webkit-transition:-webkit-transform .5s ease-in-out;-moz-transition:-moz-transform .5s ease-in-out;-o-transition:-o-transform .5s ease-in-out;transition:transform .5s ease-in-out}.direct-chat-text{border-radius:5px;position:relative;padding:5px 10px;background:#d2d6de;border:1px solid #d2d6de;margin:5px 0 0 50px;color:#444}.direct-chat-text:after,.direct-chat-text:before{position:absolute;right:100%;top:15px;border:solid transparent;border-right-color:#d2d6de;content:' ';height:0;width:0;pointer-events:none}.direct-chat-text:after{border-width:5px;margin-top:-5px}.direct-chat-text:before{border-width:6px;margin-top:-6px}.right .direct-chat-text{margin-right:50px;margin-left:0}.right .direct-chat-text:after,.right .direct-chat-text:before{right:auto;left:100%;border-right-color:transparent;border-left-color:#d2d6de}.direct-chat-img{border-radius:50%;float:left;width:40px;height:40px}.right .direct-chat-img{float:right}.direct-chat-info{display:block;margin-bottom:2px;font-size:12px}.direct-chat-name{font-weight:600}.direct-chat-timestamp{color:#999}.direct-chat-contacts-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-contacts{-webkit-transform:translate(101%, 0);-ms-transform:translate(101%, 0);-o-transform:translate(101%, 0);transform:translate(101%, 0);position:absolute;top:0;bottom:0;height:250px;width:100%;background:#222d32;color:#fff;overflow:auto}.contacts-list>li{border-bottom:1px solid rgba(0,0,0,0.2);padding:10px;margin:0}.contacts-list>li:before,.contacts-list>li:after{content:" ";display:table}.contacts-list>li:after{clear:both}.contacts-list>li:last-of-type{border-bottom:none}.contacts-list-img{border-radius:50%;width:40px;float:left}.contacts-list-info{margin-left:45px;color:#fff}.contacts-list-name,.contacts-list-status{display:block}.contacts-list-name{font-weight:600}.contacts-list-status{font-size:12px}.contacts-list-date{color:#aaa;font-weight:normal}.contacts-list-msg{color:#999}.direct-chat-danger .right>.direct-chat-text{background:#dd4b39;border-color:#dd4b39;color:#fff}.direct-chat-danger .right>.direct-chat-text:after,.direct-chat-danger .right>.direct-chat-text:before{border-left-color:#dd4b39}.direct-chat-primary .right>.direct-chat-text{background:#3c8dbc;border-color:#3c8dbc;color:#fff}.direct-chat-primary .right>.direct-chat-text:after,.direct-chat-primary .right>.direct-chat-text:before{border-left-color:#3c8dbc}.direct-chat-warning .right>.direct-chat-text{background:#f39c12;border-color:#f39c12;color:#fff}.direct-chat-warning .right>.direct-chat-text:after,.direct-chat-warning .right>.direct-chat-text:before{border-left-color:#f39c12}.direct-chat-info .right>.direct-chat-text{background:#00c0ef;border-color:#00c0ef;color:#fff}.direct-chat-info .right>.direct-chat-text:after,.direct-chat-info .right>.direct-chat-text:before{border-left-color:#00c0ef}.direct-chat-success .right>.direct-chat-text{background:#00a65a;border-color:#00a65a;color:#fff}.direct-chat-success .right>.direct-chat-text:after,.direct-chat-success .right>.direct-chat-text:before{border-left-color:#00a65a}.users-list>li{width:25%;float:left;padding:10px;text-align:center}.users-list>li img{border-radius:50%;max-width:100%;height:auto}.users-list>li>a:hover,.users-list>li>a:hover .users-list-name{color:#999}.users-list-name,.users-list-date{display:block}.users-list-name{font-weight:600;color:#444;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.users-list-date{color:#999;font-size:12px}.carousel-control.left,.carousel-control.right{background-image:none}.carousel-control>.fa{font-size:40px;position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-20px}.modal{background:rgba(0,0,0,0.3)}.modal-content{border-radius:0;-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125);border:0}@media (min-width:768px){.modal-content{-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125)}}.modal-header{border-bottom-color:#f4f4f4}.modal-footer{border-top-color:#f4f4f4}.modal-primary .modal-header,.modal-primary .modal-footer{border-color:#307095}.modal-warning .modal-header,.modal-warning .modal-footer{border-color:#c87f0a}.modal-info .modal-header,.modal-info .modal-footer{border-color:#0097bc}.modal-success .modal-header,.modal-success .modal-footer{border-color:#00733e}.modal-danger .modal-header,.modal-danger .modal-footer{border-color:#c23321}.box-widget{border:none;position:relative}.widget-user .widget-user-header{padding:20px;height:120px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user .widget-user-username{margin-top:0;margin-bottom:5px;font-size:25px;font-weight:300;text-shadow:0 1px 1px rgba(0,0,0,0.2)}.widget-user .widget-user-desc{margin-top:0}.widget-user .widget-user-image{position:absolute;top:65px;left:50%;margin-left:-45px}.widget-user .widget-user-image>img{width:90px;height:auto;border:3px solid #fff}.widget-user .box-footer{padding-top:30px}.widget-user-2 .widget-user-header{padding:20px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user-2 .widget-user-username{margin-top:5px;margin-bottom:5px;font-size:25px;font-weight:300}.widget-user-2 .widget-user-desc{margin-top:0}.widget-user-2 .widget-user-username,.widget-user-2 .widget-user-desc{margin-left:75px}.widget-user-2 .widget-user-image>img{width:65px;height:auto;float:left}.mailbox-messages>.table{margin:0}.mailbox-controls{padding:5px}.mailbox-controls.with-border{border-bottom:1px solid #f4f4f4}.mailbox-read-info{border-bottom:1px solid #f4f4f4;padding:10px}.mailbox-read-info h3{font-size:20px;margin:0}.mailbox-read-info h5{margin:0;padding:5px 0 0 0}.mailbox-read-time{color:#999;font-size:13px}.mailbox-read-message{padding:10px}.mailbox-attachments li{float:left;width:200px;border:1px solid #eee;margin-bottom:10px;margin-right:10px}.mailbox-attachment-name{font-weight:bold;color:#666}.mailbox-attachment-icon,.mailbox-attachment-info,.mailbox-attachment-size{display:block}.mailbox-attachment-info{padding:10px;background:#f4f4f4}.mailbox-attachment-size{color:#999;font-size:12px}.mailbox-attachment-icon{text-align:center;font-size:65px;color:#666;padding:20px 10px}.mailbox-attachment-icon.has-img{padding:0}.mailbox-attachment-icon.has-img>img{max-width:100%;height:auto}.lockscreen{background:#d2d6de}.lockscreen-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.lockscreen-logo a{color:#444}.lockscreen-wrapper{max-width:400px;margin:0 auto;margin-top:10%}.lockscreen .lockscreen-name{text-align:center;font-weight:600}.lockscreen-item{border-radius:4px;padding:0;background:#fff;position:relative;margin:10px auto 30px auto;width:290px}.lockscreen-image{border-radius:50%;position:absolute;left:-10px;top:-25px;background:#fff;padding:5px;z-index:10}.lockscreen-image>img{border-radius:50%;width:70px;height:70px}.lockscreen-credentials{margin-left:70px}.lockscreen-credentials .form-control{border:0}.lockscreen-credentials .btn{background-color:#fff;border:0;padding:0 10px}.lockscreen-footer{margin-top:10px}.login-logo,.register-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.login-logo a,.register-logo a{color:#444}.login-page,.register-page{background:#d2d6de}.login-box,.register-box{width:360px;margin:7% auto}@media (max-width:768px){.login-box,.register-box{width:90%;margin-top:20px}}.login-box-body,.register-box-body{background:#fff;padding:20px;border-top:0;color:#666}.login-box-body .form-control-feedback,.register-box-body .form-control-feedback{color:#777}.login-box-msg,.register-box-msg{margin:0;text-align:center;padding:0 20px 20px 20px}.social-auth-links{margin:10px 0}.error-page{width:600px;margin:20px auto 0 auto}@media (max-width:991px){.error-page{width:100%}}.error-page>.headline{float:left;font-size:100px;font-weight:300}@media (max-width:991px){.error-page>.headline{float:none;text-align:center}}.error-page>.error-content{margin-left:190px;display:block}@media (max-width:991px){.error-page>.error-content{margin-left:0}}.error-page>.error-content>h3{font-weight:300;font-size:25px}@media (max-width:991px){.error-page>.error-content>h3{text-align:center}}.invoice{position:relative;background:#fff;border:1px solid #f4f4f4;padding:20px;margin:10px 25px}.invoice-title{margin-top:0}.profile-user-img{margin:0 auto;width:100px;padding:3px;border:3px solid #d2d6de}.profile-username{font-size:21px;margin-top:5px}.post{border-bottom:1px solid #d2d6de;margin-bottom:15px;padding-bottom:15px;color:#666}.post:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.post .user-block{margin-bottom:15px}.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding:0}.btn-social-icon>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon>:first-child{border:none;text-align:center;width:100%}.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0}.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0}.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0}.btn-adn{color:#fff;background-color:#d87a68;border-color:rgba(0,0,0,0.2)}.btn-adn:focus,.btn-adn.focus{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:hover{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{background-image:none}.btn-adn .badge{color:#d87a68;background-color:#fff}.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:focus,.btn-bitbucket.focus{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:hover{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{background-image:none}.btn-bitbucket .badge{color:#205081;background-color:#fff}.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:focus,.btn-dropbox.focus{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:hover{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{background-image:none}.btn-dropbox .badge{color:#1087dd;background-color:#fff}.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:focus,.btn-facebook.focus{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:hover{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{background-image:none}.btn-facebook .badge{color:#3b5998;background-color:#fff}.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:focus,.btn-flickr.focus{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:hover{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{background-image:none}.btn-flickr .badge{color:#ff0084;background-color:#fff}.btn-foursquare{color:#fff;background-color:#f94877;border-color:rgba(0,0,0,0.2)}.btn-foursquare:focus,.btn-foursquare.focus{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:hover{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{background-image:none}.btn-foursquare .badge{color:#f94877;background-color:#fff}.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:focus,.btn-github.focus{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:hover{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{background-image:none}.btn-github .badge{color:#444;background-color:#fff}.btn-google{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google:focus,.btn-google.focus{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:hover{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{background-image:none}.btn-google .badge{color:#dd4b39;background-color:#fff}.btn-instagram{color:#fff;background-color:#3f729b;border-color:rgba(0,0,0,0.2)}.btn-instagram:focus,.btn-instagram.focus{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:hover{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{background-image:none}.btn-instagram .badge{color:#3f729b;background-color:#fff}.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:focus,.btn-linkedin.focus{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:hover{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{background-image:none}.btn-linkedin .badge{color:#007bb6;background-color:#fff}.btn-microsoft{color:#fff;background-color:#2672ec;border-color:rgba(0,0,0,0.2)}.btn-microsoft:focus,.btn-microsoft.focus{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:hover{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{background-image:none}.btn-microsoft .badge{color:#2672ec;background-color:#fff}.btn-openid{color:#fff;background-color:#f7931e;border-color:rgba(0,0,0,0.2)}.btn-openid:focus,.btn-openid.focus{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:hover{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{background-image:none}.btn-openid .badge{color:#f7931e;background-color:#fff}.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:focus,.btn-pinterest.focus{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:hover{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{background-image:none}.btn-pinterest .badge{color:#cb2027;background-color:#fff}.btn-reddit{color:#000;background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}.btn-reddit:focus,.btn-reddit.focus{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:hover{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{background-image:none}.btn-reddit .badge{color:#eff7ff;background-color:#000}.btn-soundcloud{color:#fff;background-color:#f50;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:focus,.btn-soundcloud.focus{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:hover{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{background-image:none}.btn-soundcloud .badge{color:#f50;background-color:#fff}.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:focus,.btn-tumblr.focus{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:hover{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{background-image:none}.btn-tumblr .badge{color:#2c4762;background-color:#fff}.btn-twitter{color:#fff;background-color:#55acee;border-color:rgba(0,0,0,0.2)}.btn-twitter:focus,.btn-twitter.focus{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:hover{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{background-image:none}.btn-twitter .badge{color:#55acee;background-color:#fff}.btn-vimeo{color:#fff;background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}.btn-vimeo:focus,.btn-vimeo.focus{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:hover{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{background-image:none}.btn-vimeo .badge{color:#1ab7ea;background-color:#fff}.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:focus,.btn-vk.focus{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:hover{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{background-image:none}.btn-vk .badge{color:#587ea3;background-color:#fff}.btn-yahoo{color:#fff;background-color:#720e9e;border-color:rgba(0,0,0,0.2)}.btn-yahoo:focus,.btn-yahoo.focus{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:hover{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{background-image:none}.btn-yahoo .badge{color:#720e9e;background-color:#fff}.fc-button{background:#f4f4f4;background-image:none;color:#444;border-color:#ddd;border-bottom-color:#ddd}.fc-button:hover,.fc-button:active,.fc-button.hover{background-color:#e9e9e9}.fc-header-title h2{font-size:15px;line-height:1.6em;color:#666;margin-left:10px}.fc-header-right{padding-right:10px}.fc-header-left{padding-left:10px}.fc-widget-header{background:#fafafa}.fc-grid{width:100%;border:0}.fc-widget-header:first-of-type,.fc-widget-content:first-of-type{border-left:0;border-right:0}.fc-widget-header:last-of-type,.fc-widget-content:last-of-type{border-right:0}.fc-toolbar{padding:10px;margin:0}.fc-day-number{font-size:20px;font-weight:300;padding-right:10px}.fc-color-picker{list-style:none;margin:0;padding:0}.fc-color-picker>li{float:left;font-size:30px;margin-right:5px;line-height:30px}.fc-color-picker>li .fa{-webkit-transition:-webkit-transform linear .3s;-moz-transition:-moz-transform linear .3s;-o-transition:-o-transform linear .3s;transition:transform linear .3s}.fc-color-picker>li .fa:hover{-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}#add-new-event{-webkit-transition:all linear .3s;-o-transition:all linear .3s;transition:all linear .3s}.external-event{padding:5px 10px;font-weight:bold;margin-bottom:4px;box-shadow:0 1px 1px rgba(0,0,0,0.1);text-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;cursor:move}.external-event:hover{box-shadow:inset 0 0 90px rgba(0,0,0,0.2)}.select2-container--default.select2-container--focus,.select2-selection.select2-container--focus,.select2-container--default:focus,.select2-selection:focus,.select2-container--default:active,.select2-selection:active{outline:none}.select2-container--default .select2-selection--single,.select2-selection .select2-selection--single{border:1px solid #d2d6de;border-radius:0;padding:6px 12px;height:34px}.select2-container--default.select2-container--open{border-color:#3c8dbc}.select2-dropdown{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#3c8dbc;color:white}.select2-results__option{padding:6px 12px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{padding-left:0;padding-right:0;height:auto;margin-top:-4px}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:6px;padding-left:20px}.select2-container--default .select2-selection--single .select2-selection__arrow{height:28px;right:3px}.select2-container--default .select2-selection--single .select2-selection__arrow b{margin-top:0}.select2-dropdown .select2-search__field,.select2-search--inline .select2-search__field{border:1px solid #d2d6de}.select2-dropdown .select2-search__field:focus,.select2-search--inline .select2-search__field:focus{outline:none;border:1px solid #3c8dbc}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option[aria-selected=true],.select2-container--default .select2-results__option[aria-selected=true]:hover{color:#444}.select2-container--default .select2-selection--multiple{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-selection--multiple:focus{border-color:#3c8dbc}.select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#d2d6de}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc;border-color:#367fa9;padding:1px 10px;color:#fff}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{margin-right:5px;color:rgba(255,255,255,0.7)}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container .select2-selection--single .select2-selection__rendered{padding-right:10px}.pad{padding:10px}.margin{margin:10px}.margin-bottom{margin-bottom:20px}.margin-bottom-none{margin-bottom:0}.margin-r-5{margin-right:5px}.inline{display:inline}.description-block{display:block;margin:10px 0;text-align:center}.description-block.margin-bottom{margin-bottom:25px}.description-block>.description-header{margin:0;padding:0;font-weight:600;font-size:16px}.description-block>.description-text{text-transform:uppercase}.bg-red,.bg-yellow,.bg-aqua,.bg-blue,.bg-light-blue,.bg-green,.bg-navy,.bg-teal,.bg-olive,.bg-lime,.bg-orange,.bg-fuchsia,.bg-purple,.bg-maroon,.bg-black,.bg-red-active,.bg-yellow-active,.bg-aqua-active,.bg-blue-active,.bg-light-blue-active,.bg-green-active,.bg-navy-active,.bg-teal-active,.bg-olive-active,.bg-lime-active,.bg-orange-active,.bg-fuchsia-active,.bg-purple-active,.bg-maroon-active,.bg-black-active,.callout.callout-danger,.callout.callout-warning,.callout.callout-info,.callout.callout-success,.alert-success,.alert-danger,.alert-error,.alert-warning,.alert-info,.label-danger,.label-info,.label-warning,.label-primary,.label-success,.modal-primary .modal-body,.modal-primary .modal-header,.modal-primary .modal-footer,.modal-warning .modal-body,.modal-warning .modal-header,.modal-warning .modal-footer,.modal-info .modal-body,.modal-info .modal-header,.modal-info .modal-footer,.modal-success .modal-body,.modal-success .modal-header,.modal-success .modal-footer,.modal-danger .modal-body,.modal-danger .modal-header,.modal-danger .modal-footer{color:#fff !important}.bg-gray{color:#000;background-color:#d2d6de !important}.bg-gray-light{background-color:#f7f7f7}.bg-black{background-color:#111 !important}.bg-red,.callout.callout-danger,.alert-danger,.alert-error,.label-danger,.modal-danger .modal-body{background-color:#dd4b39 !important}.bg-yellow,.callout.callout-warning,.alert-warning,.label-warning,.modal-warning .modal-body{background-color:#f39c12 !important}.bg-aqua,.callout.callout-info,.alert-info,.label-info,.modal-info .modal-body{background-color:#00c0ef !important}.bg-blue{background-color:#0073b7 !important}.bg-light-blue,.label-primary,.modal-primary .modal-body{background-color:#3c8dbc !important}.bg-green,.callout.callout-success,.alert-success,.label-success,.modal-success .modal-body{background-color:#00a65a !important}.bg-navy{background-color:#001f3f !important}.bg-teal{background-color:#39cccc !important}.bg-olive{background-color:#3d9970 !important}.bg-lime{background-color:#01ff70 !important}.bg-orange{background-color:#ff851b !important}.bg-fuchsia{background-color:#f012be !important}.bg-purple{background-color:#605ca8 !important}.bg-maroon{background-color:#d81b60 !important}.bg-gray-active{color:#000;background-color:#b5bbc8 !important}.bg-black-active{background-color:#000 !important}.bg-red-active,.modal-danger .modal-header,.modal-danger .modal-footer{background-color:#d33724 !important}.bg-yellow-active,.modal-warning .modal-header,.modal-warning .modal-footer{background-color:#db8b0b !important}.bg-aqua-active,.modal-info .modal-header,.modal-info .modal-footer{background-color:#00a7d0 !important}.bg-blue-active{background-color:#005384 !important}.bg-light-blue-active,.modal-primary .modal-header,.modal-primary .modal-footer{background-color:#357ca5 !important}.bg-green-active,.modal-success .modal-header,.modal-success .modal-footer{background-color:#008d4c !important}.bg-navy-active{background-color:#001a35 !important}.bg-teal-active{background-color:#30bbbb !important}.bg-olive-active{background-color:#368763 !important}.bg-lime-active{background-color:#00e765 !important}.bg-orange-active{background-color:#ff7701 !important}.bg-fuchsia-active{background-color:#db0ead !important}.bg-purple-active{background-color:#555299 !important}.bg-maroon-active{background-color:#ca195a !important}[class^="bg-"].disabled{opacity:.65;filter:alpha(opacity=65)}.text-red{color:#dd4b39 !important}.text-yellow{color:#f39c12 !important}.text-aqua{color:#00c0ef !important}.text-blue{color:#0073b7 !important}.text-black{color:#111 !important}.text-light-blue{color:#3c8dbc !important}.text-green{color:#00a65a !important}.text-gray{color:#d2d6de !important}.text-navy{color:#001f3f !important}.text-teal{color:#39cccc !important}.text-olive{color:#3d9970 !important}.text-lime{color:#01ff70 !important}.text-orange{color:#ff851b !important}.text-fuchsia{color:#f012be !important}.text-purple{color:#605ca8 !important}.text-maroon{color:#d81b60 !important}.link-muted{color:#7a869d}.link-muted:hover,.link-muted:focus{color:#606c84}.link-black{color:#666}.link-black:hover,.link-black:focus{color:#999}.hide{display:none !important}.no-border{border:0 !important}.no-padding{padding:0 !important}.no-margin{margin:0 !important}.no-shadow{box-shadow:none !important}.list-unstyled,.chart-legend,.contacts-list,.users-list,.mailbox-attachments{list-style:none;margin:0;padding:0}.list-group-unbordered>.list-group-item{border-left:0;border-right:0;border-radius:0;padding-left:0;padding-right:0}.flat{border-radius:0 !important}.text-bold,.text-bold.table td,.text-bold.table th{font-weight:700}.text-sm{font-size:12px}.jqstooltip{padding:5px !important;width:auto !important;height:auto !important}.bg-teal-gradient{background:#39cccc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;background:-ms-linear-gradient(bottom, #39cccc, #7adddd) !important;background:-moz-linear-gradient(center bottom, #39cccc 0, #7adddd 100%) !important;background:-o-linear-gradient(#7adddd, #39cccc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important;color:#fff}.bg-light-blue-gradient{background:#3c8dbc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;background:-ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;background:-moz-linear-gradient(center bottom, #3c8dbc 0, #67a8ce 100%) !important;background:-o-linear-gradient(#67a8ce, #3c8dbc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;color:#fff}.bg-blue-gradient{background:#0073b7 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;background:-ms-linear-gradient(bottom, #0073b7, #0089db) !important;background:-moz-linear-gradient(center bottom, #0073b7 0, #0089db 100%) !important;background:-o-linear-gradient(#0089db, #0073b7) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;color:#fff}.bg-aqua-gradient{background:#00c0ef !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important;background:-ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important;background:-moz-linear-gradient(center bottom, #00c0ef 0, #14d1ff 100%) !important;background:-o-linear-gradient(#14d1ff, #00c0ef) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important;color:#fff}.bg-yellow-gradient{background:#f39c12 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important;background:-ms-linear-gradient(bottom, #f39c12, #f7bc60) !important;background:-moz-linear-gradient(center bottom, #f39c12 0, #f7bc60 100%) !important;background:-o-linear-gradient(#f7bc60, #f39c12) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important;color:#fff}.bg-purple-gradient{background:#605ca8 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #605ca8), color-stop(1, #9491c4)) !important;background:-ms-linear-gradient(bottom, #605ca8, #9491c4) !important;background:-moz-linear-gradient(center bottom, #605ca8 0, #9491c4 100%) !important;background:-o-linear-gradient(#9491c4, #605ca8) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9491c4', endColorstr='#605ca8', GradientType=0) !important;color:#fff}.bg-green-gradient{background:#00a65a !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important;background:-ms-linear-gradient(bottom, #00a65a, #00ca6d) !important;background:-moz-linear-gradient(center bottom, #00a65a 0, #00ca6d 100%) !important;background:-o-linear-gradient(#00ca6d, #00a65a) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important;color:#fff}.bg-red-gradient{background:#dd4b39 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #dd4b39), color-stop(1, #e47365)) !important;background:-ms-linear-gradient(bottom, #dd4b39, #e47365) !important;background:-moz-linear-gradient(center bottom, #dd4b39 0, #e47365 100%) !important;background:-o-linear-gradient(#e47365, #dd4b39) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e47365', endColorstr='#dd4b39', GradientType=0) !important;color:#fff}.bg-black-gradient{background:#111 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #111), color-stop(1, #2b2b2b)) !important;background:-ms-linear-gradient(bottom, #111, #2b2b2b) !important;background:-moz-linear-gradient(center bottom, #111 0, #2b2b2b 100%) !important;background:-o-linear-gradient(#2b2b2b, #111) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#2b2b2b', endColorstr='#111111', GradientType=0) !important;color:#fff}.bg-maroon-gradient{background:#d81b60 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #d81b60), color-stop(1, #e73f7c)) !important;background:-ms-linear-gradient(bottom, #d81b60, #e73f7c) !important;background:-moz-linear-gradient(center bottom, #d81b60 0, #e73f7c 100%) !important;background:-o-linear-gradient(#e73f7c, #d81b60) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e73f7c', endColorstr='#d81b60', GradientType=0) !important;color:#fff}.description-block .description-icon{font-size:16px}.no-pad-top{padding-top:0}.position-static{position:static !important}.list-header{font-size:15px;padding:10px 4px;font-weight:bold;color:#666}.list-seperator{height:1px;background:#f4f4f4;margin:15px 0 9px 0}.list-link>a{padding:4px;color:#777}.list-link>a:hover{color:#222}.font-light{font-weight:300}.user-block:before,.user-block:after{content:" ";display:table}.user-block:after{clear:both}.user-block img{width:40px;height:40px;float:left}.user-block .username,.user-block .description,.user-block .comment{display:block;margin-left:50px}.user-block .username{font-size:16px;font-weight:600}.user-block .description{color:#999;font-size:13px}.user-block.user-block-sm .username,.user-block.user-block-sm .description,.user-block.user-block-sm .comment{margin-left:40px}.user-block.user-block-sm .username{font-size:14px}.img-sm,.img-md,.img-lg,.box-comments .box-comment img,.user-block.user-block-sm img{float:left}.img-sm,.box-comments .box-comment img,.user-block.user-block-sm img{width:30px !important;height:30px !important}.img-sm+.img-push{margin-left:40px}.img-md{width:60px;height:60px}.img-md+.img-push{margin-left:70px}.img-lg{width:100px;height:100px}.img-lg+.img-push{margin-left:110px}.img-bordered{border:3px solid #d2d6de;padding:3px}.img-bordered-sm{border:2px solid #d2d6de;padding:2px}.attachment-block{border:1px solid #f4f4f4;padding:5px;margin-bottom:10px;background:#f7f7f7}.attachment-block .attachment-img{max-width:100px;max-height:100px;height:auto;float:left}.attachment-block .attachment-pushed{margin-left:110px}.attachment-block .attachment-heading{margin:0}.attachment-block .attachment-text{color:#555}.connectedSortable{min-height:100px}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sort-highlight{background:#f4f4f4;border:1px dashed #ddd;margin-bottom:10px}.full-opacity-hover{opacity:.65;filter:alpha(opacity=65)}.full-opacity-hover:hover{opacity:1;filter:alpha(opacity=100)}.chart{position:relative;overflow:hidden;width:100%}.chart svg,.chart canvas{width:100% !important}@media print{.no-print,.main-sidebar,.left-side,.main-header,.content-header{display:none !important}.content-wrapper,.right-side,.main-footer{margin-left:0 !important;min-height:0 !important;-webkit-transform:translate(0, 0) !important;-ms-transform:translate(0, 0) !important;-o-transform:translate(0, 0) !important;transform:translate(0, 0) !important}.fixed .content-wrapper,.fixed .right-side{padding-top:0 !important}.invoice{width:100%;border:0;margin:0;padding:0}.invoice-col{float:left;width:33.3333333%}.table-responsive{overflow:auto}.table-responsive>.table tr th,.table-responsive>.table tr td{white-space:normal !important}} \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/css/all-skins.min.css b/renren-generator/src/main/resources/static/css/all-skins.min.css new file mode 100644 index 0000000..e1d2398 --- /dev/null +++ b/renren-generator/src/main/resources/static/css/all-skins.min.css @@ -0,0 +1 @@ +.skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header .logo{background-color:#367fa9;color:#fff;border-bottom:0 solid transparent}.skin-blue .main-header .logo:hover{background-color:#357ca5}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:transparent}.skin-blue .wrapper,.skin-blue .main-sidebar,.skin-blue .left-side{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li:hover>a,.skin-blue .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .treeview-menu>li>a{color:#8aa4af}.skin-blue .treeview-menu>li.active>a,.skin-blue .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-blue .sidebar-form input[type="text"],.skin-blue .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-blue .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type="text"]:focus,.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8}.skin-blue-light .main-header .navbar{background-color:#3c8dbc}.skin-blue-light .main-header .navbar .nav>li>a{color:#fff}.skin-blue-light .main-header .navbar .nav>li>a:hover,.skin-blue-light .main-header .navbar .nav>li>a:active,.skin-blue-light .main-header .navbar .nav>li>a:focus,.skin-blue-light .main-header .navbar .nav .open>a,.skin-blue-light .main-header .navbar .nav .open>a:hover,.skin-blue-light .main-header .navbar .nav .open>a:focus,.skin-blue-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue-light .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue-light .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue-light .main-header .logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue-light .main-header .logo:hover{background-color:#3b8ab8}.skin-blue-light .main-header li.user-header{background-color:#3c8dbc}.skin-blue-light .content-header{background:transparent}.skin-blue-light .wrapper,.skin-blue-light .main-sidebar,.skin-blue-light .left-side{background-color:#f9fafc}.skin-blue-light .content-wrapper,.skin-blue-light .main-footer{border-left:1px solid #d2d6de}.skin-blue-light .user-panel>.info,.skin-blue-light .user-panel>.info>a{color:#444}.skin-blue-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-blue-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-blue-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-blue-light .sidebar-menu>li:hover>a,.skin-blue-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-blue-light .sidebar-menu>li.active{border-left-color:#3c8dbc}.skin-blue-light .sidebar-menu>li.active>a{font-weight:600}.skin-blue-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-blue-light .sidebar a{color:#444}.skin-blue-light .sidebar a:hover{text-decoration:none}.skin-blue-light .treeview-menu>li>a{color:#777}.skin-blue-light .treeview-menu>li.active>a,.skin-blue-light .treeview-menu>li>a:hover{color:#000}.skin-blue-light .treeview-menu>li.active>a{font-weight:600}.skin-blue-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-blue-light .sidebar-form input[type="text"],.skin-blue-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-blue-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue-light .sidebar-form input[type="text"]:focus,.skin-blue-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-blue-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-blue-light .main-footer{border-top-color:#d2d6de}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8}.skin-black .main-header{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.skin-black .main-header .navbar-toggle{color:#333}.skin-black .main-header .navbar-brand{color:#333;border-right:1px solid #eee}.skin-black .main-header .navbar{background-color:#fff}.skin-black .main-header .navbar .nav>li>a{color:#333}.skin-black .main-header .navbar .nav>li>a:hover,.skin-black .main-header .navbar .nav>li>a:active,.skin-black .main-header .navbar .nav>li>a:focus,.skin-black .main-header .navbar .nav .open>a,.skin-black .main-header .navbar .nav .open>a:hover,.skin-black .main-header .navbar .nav .open>a:focus,.skin-black .main-header .navbar .nav>.active>a{background:#fff;color:#999}.skin-black .main-header .navbar .sidebar-toggle{color:#333}.skin-black .main-header .navbar .sidebar-toggle:hover{color:#999;background:#fff}.skin-black .main-header .navbar>.sidebar-toggle{color:#333;border-right:1px solid #eee}.skin-black .main-header .navbar .navbar-nav>li>a{border-right:1px solid #eee}.skin-black .main-header .navbar .navbar-custom-menu .navbar-nav>li>a,.skin-black .main-header .navbar .navbar-right>li>a{border-left:1px solid #eee;border-right-width:0}.skin-black .main-header>.logo{background-color:#fff;color:#333;border-bottom:0 solid transparent;border-right:1px solid #eee}.skin-black .main-header>.logo:hover{background-color:#fcfcfc}@media (max-width:767px){.skin-black .main-header>.logo{background-color:#222;color:#fff;border-bottom:0 solid transparent;border-right:none}.skin-black .main-header>.logo:hover{background-color:#1f1f1f}}.skin-black .main-header li.user-header{background-color:#222}.skin-black .content-header{background:transparent;box-shadow:none}.skin-black .wrapper,.skin-black .main-sidebar,.skin-black .left-side{background-color:#222d32}.skin-black .user-panel>.info,.skin-black .user-panel>.info>a{color:#fff}.skin-black .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-black .sidebar-menu>li>a{border-left:3px solid transparent}.skin-black .sidebar-menu>li:hover>a,.skin-black .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#fff}.skin-black .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-black .sidebar a{color:#b8c7ce}.skin-black .sidebar a:hover{text-decoration:none}.skin-black .treeview-menu>li>a{color:#8aa4af}.skin-black .treeview-menu>li.active>a,.skin-black .treeview-menu>li>a:hover{color:#fff}.skin-black .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-black .sidebar-form input[type="text"],.skin-black .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-black .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black .sidebar-form input[type="text"]:focus,.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-black .pace .pace-progress{background:#222}.skin-black .pace .pace-activity{border-top-color:#222;border-left-color:#222}.skin-black-light .main-header{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.skin-black-light .main-header .navbar-toggle{color:#333}.skin-black-light .main-header .navbar-brand{color:#333;border-right:1px solid #eee}.skin-black-light .main-header .navbar{background-color:#fff}.skin-black-light .main-header .navbar .nav>li>a{color:#333}.skin-black-light .main-header .navbar .nav>li>a:hover,.skin-black-light .main-header .navbar .nav>li>a:active,.skin-black-light .main-header .navbar .nav>li>a:focus,.skin-black-light .main-header .navbar .nav .open>a,.skin-black-light .main-header .navbar .nav .open>a:hover,.skin-black-light .main-header .navbar .nav .open>a:focus,.skin-black-light .main-header .navbar .nav>.active>a{background:#fff;color:#999}.skin-black-light .main-header .navbar .sidebar-toggle{color:#333}.skin-black-light .main-header .navbar .sidebar-toggle:hover{color:#999;background:#fff}.skin-black-light .main-header .navbar>.sidebar-toggle{color:#333;border-right:1px solid #eee}.skin-black-light .main-header .navbar .navbar-nav>li>a{border-right:1px solid #eee}.skin-black-light .main-header .navbar .navbar-custom-menu .navbar-nav>li>a,.skin-black-light .main-header .navbar .navbar-right>li>a{border-left:1px solid #eee;border-right-width:0}.skin-black-light .main-header>.logo{background-color:#fff;color:#333;border-bottom:0 solid transparent;border-right:1px solid #eee}.skin-black-light .main-header>.logo:hover{background-color:#fcfcfc}@media (max-width:767px){.skin-black-light .main-header>.logo{background-color:#222;color:#fff;border-bottom:0 solid transparent;border-right:none}.skin-black-light .main-header>.logo:hover{background-color:#1f1f1f}}.skin-black-light .main-header li.user-header{background-color:#222}.skin-black-light .content-header{background:transparent;box-shadow:none}.skin-black-light .wrapper,.skin-black-light .main-sidebar,.skin-black-light .left-side{background-color:#f9fafc}.skin-black-light .content-wrapper,.skin-black-light .main-footer{border-left:1px solid #d2d6de}.skin-black-light .user-panel>.info,.skin-black-light .user-panel>.info>a{color:#444}.skin-black-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-black-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-black-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-black-light .sidebar-menu>li:hover>a,.skin-black-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-black-light .sidebar-menu>li.active{border-left-color:#fff}.skin-black-light .sidebar-menu>li.active>a{font-weight:600}.skin-black-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-black-light .sidebar a{color:#444}.skin-black-light .sidebar a:hover{text-decoration:none}.skin-black-light .treeview-menu>li>a{color:#777}.skin-black-light .treeview-menu>li.active>a,.skin-black-light .treeview-menu>li>a:hover{color:#000}.skin-black-light .treeview-menu>li.active>a{font-weight:600}.skin-black-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-black-light .sidebar-form input[type="text"],.skin-black-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-black-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black-light .sidebar-form input[type="text"]:focus,.skin-black-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-green .main-header .navbar{background-color:#00a65a}.skin-green .main-header .navbar .nav>li>a{color:#fff}.skin-green .main-header .navbar .nav>li>a:hover,.skin-green .main-header .navbar .nav>li>a:active,.skin-green .main-header .navbar .nav>li>a:focus,.skin-green .main-header .navbar .nav .open>a,.skin-green .main-header .navbar .nav .open>a:hover,.skin-green .main-header .navbar .nav .open>a:focus,.skin-green .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green .main-header .logo{background-color:#008d4c;color:#fff;border-bottom:0 solid transparent}.skin-green .main-header .logo:hover{background-color:#008749}.skin-green .main-header li.user-header{background-color:#00a65a}.skin-green .content-header{background:transparent}.skin-green .wrapper,.skin-green .main-sidebar,.skin-green .left-side{background-color:#222d32}.skin-green .user-panel>.info,.skin-green .user-panel>.info>a{color:#fff}.skin-green .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-green .sidebar-menu>li>a{border-left:3px solid transparent}.skin-green .sidebar-menu>li:hover>a,.skin-green .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#00a65a}.skin-green .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-green .sidebar a{color:#b8c7ce}.skin-green .sidebar a:hover{text-decoration:none}.skin-green .treeview-menu>li>a{color:#8aa4af}.skin-green .treeview-menu>li.active>a,.skin-green .treeview-menu>li>a:hover{color:#fff}.skin-green .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-green .sidebar-form input[type="text"],.skin-green .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-green .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green .sidebar-form input[type="text"]:focus,.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-green-light .main-header .navbar{background-color:#00a65a}.skin-green-light .main-header .navbar .nav>li>a{color:#fff}.skin-green-light .main-header .navbar .nav>li>a:hover,.skin-green-light .main-header .navbar .nav>li>a:active,.skin-green-light .main-header .navbar .nav>li>a:focus,.skin-green-light .main-header .navbar .nav .open>a,.skin-green-light .main-header .navbar .nav .open>a:hover,.skin-green-light .main-header .navbar .nav .open>a:focus,.skin-green-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-green-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-green-light .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green-light .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green-light .main-header .logo{background-color:#00a65a;color:#fff;border-bottom:0 solid transparent}.skin-green-light .main-header .logo:hover{background-color:#00a157}.skin-green-light .main-header li.user-header{background-color:#00a65a}.skin-green-light .content-header{background:transparent}.skin-green-light .wrapper,.skin-green-light .main-sidebar,.skin-green-light .left-side{background-color:#f9fafc}.skin-green-light .content-wrapper,.skin-green-light .main-footer{border-left:1px solid #d2d6de}.skin-green-light .user-panel>.info,.skin-green-light .user-panel>.info>a{color:#444}.skin-green-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-green-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-green-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-green-light .sidebar-menu>li:hover>a,.skin-green-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-green-light .sidebar-menu>li.active{border-left-color:#00a65a}.skin-green-light .sidebar-menu>li.active>a{font-weight:600}.skin-green-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-green-light .sidebar a{color:#444}.skin-green-light .sidebar a:hover{text-decoration:none}.skin-green-light .treeview-menu>li>a{color:#777}.skin-green-light .treeview-menu>li.active>a,.skin-green-light .treeview-menu>li>a:hover{color:#000}.skin-green-light .treeview-menu>li.active>a{font-weight:600}.skin-green-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-green-light .sidebar-form input[type="text"],.skin-green-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-green-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green-light .sidebar-form input[type="text"]:focus,.skin-green-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-green-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-red .main-header .navbar{background-color:#dd4b39}.skin-red .main-header .navbar .nav>li>a{color:#fff}.skin-red .main-header .navbar .nav>li>a:hover,.skin-red .main-header .navbar .nav>li>a:active,.skin-red .main-header .navbar .nav>li>a:focus,.skin-red .main-header .navbar .nav .open>a,.skin-red .main-header .navbar .nav .open>a:hover,.skin-red .main-header .navbar .nav .open>a:focus,.skin-red .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red .main-header .logo{background-color:#d73925;color:#fff;border-bottom:0 solid transparent}.skin-red .main-header .logo:hover{background-color:#d33724}.skin-red .main-header li.user-header{background-color:#dd4b39}.skin-red .content-header{background:transparent}.skin-red .wrapper,.skin-red .main-sidebar,.skin-red .left-side{background-color:#222d32}.skin-red .user-panel>.info,.skin-red .user-panel>.info>a{color:#fff}.skin-red .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-red .sidebar-menu>li>a{border-left:3px solid transparent}.skin-red .sidebar-menu>li:hover>a,.skin-red .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#dd4b39}.skin-red .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-red .sidebar a{color:#b8c7ce}.skin-red .sidebar a:hover{text-decoration:none}.skin-red .treeview-menu>li>a{color:#8aa4af}.skin-red .treeview-menu>li.active>a,.skin-red .treeview-menu>li>a:hover{color:#fff}.skin-red .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-red .sidebar-form input[type="text"],.skin-red .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-red .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red .sidebar-form input[type="text"]:focus,.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-red-light .main-header .navbar{background-color:#dd4b39}.skin-red-light .main-header .navbar .nav>li>a{color:#fff}.skin-red-light .main-header .navbar .nav>li>a:hover,.skin-red-light .main-header .navbar .nav>li>a:active,.skin-red-light .main-header .navbar .nav>li>a:focus,.skin-red-light .main-header .navbar .nav .open>a,.skin-red-light .main-header .navbar .nav .open>a:hover,.skin-red-light .main-header .navbar .nav .open>a:focus,.skin-red-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red-light .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red-light .main-header .logo{background-color:#dd4b39;color:#fff;border-bottom:0 solid transparent}.skin-red-light .main-header .logo:hover{background-color:#dc4735}.skin-red-light .main-header li.user-header{background-color:#dd4b39}.skin-red-light .content-header{background:transparent}.skin-red-light .wrapper,.skin-red-light .main-sidebar,.skin-red-light .left-side{background-color:#f9fafc}.skin-red-light .content-wrapper,.skin-red-light .main-footer{border-left:1px solid #d2d6de}.skin-red-light .user-panel>.info,.skin-red-light .user-panel>.info>a{color:#444}.skin-red-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-red-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-red-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-red-light .sidebar-menu>li:hover>a,.skin-red-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-red-light .sidebar-menu>li.active{border-left-color:#dd4b39}.skin-red-light .sidebar-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-red-light .sidebar a{color:#444}.skin-red-light .sidebar a:hover{text-decoration:none}.skin-red-light .treeview-menu>li>a{color:#777}.skin-red-light .treeview-menu>li.active>a,.skin-red-light .treeview-menu>li>a:hover{color:#000}.skin-red-light .treeview-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-red-light .sidebar-form input[type="text"],.skin-red-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-red-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red-light .sidebar-form input[type="text"]:focus,.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-yellow .main-header .navbar{background-color:#f39c12}.skin-yellow .main-header .navbar .nav>li>a{color:#fff}.skin-yellow .main-header .navbar .nav>li>a:hover,.skin-yellow .main-header .navbar .nav>li>a:active,.skin-yellow .main-header .navbar .nav>li>a:focus,.skin-yellow .main-header .navbar .nav .open>a,.skin-yellow .main-header .navbar .nav .open>a:hover,.skin-yellow .main-header .navbar .nav .open>a:focus,.skin-yellow .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-yellow .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow .main-header .logo{background-color:#e08e0b;color:#fff;border-bottom:0 solid transparent}.skin-yellow .main-header .logo:hover{background-color:#db8b0b}.skin-yellow .main-header li.user-header{background-color:#f39c12}.skin-yellow .content-header{background:transparent}.skin-yellow .wrapper,.skin-yellow .main-sidebar,.skin-yellow .left-side{background-color:#222d32}.skin-yellow .user-panel>.info,.skin-yellow .user-panel>.info>a{color:#fff}.skin-yellow .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-yellow .sidebar-menu>li>a{border-left:3px solid transparent}.skin-yellow .sidebar-menu>li:hover>a,.skin-yellow .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#f39c12}.skin-yellow .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-yellow .sidebar a{color:#b8c7ce}.skin-yellow .sidebar a:hover{text-decoration:none}.skin-yellow .treeview-menu>li>a{color:#8aa4af}.skin-yellow .treeview-menu>li.active>a,.skin-yellow .treeview-menu>li>a:hover{color:#fff}.skin-yellow .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-yellow .sidebar-form input[type="text"],.skin-yellow .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-yellow .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow .sidebar-form input[type="text"]:focus,.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-yellow-light .main-header .navbar{background-color:#f39c12}.skin-yellow-light .main-header .navbar .nav>li>a{color:#fff}.skin-yellow-light .main-header .navbar .nav>li>a:hover,.skin-yellow-light .main-header .navbar .nav>li>a:active,.skin-yellow-light .main-header .navbar .nav>li>a:focus,.skin-yellow-light .main-header .navbar .nav .open>a,.skin-yellow-light .main-header .navbar .nav .open>a:hover,.skin-yellow-light .main-header .navbar .nav .open>a:focus,.skin-yellow-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-yellow-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-yellow-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow-light .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-yellow-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow-light .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow-light .main-header .logo{background-color:#f39c12;color:#fff;border-bottom:0 solid transparent}.skin-yellow-light .main-header .logo:hover{background-color:#f39a0d}.skin-yellow-light .main-header li.user-header{background-color:#f39c12}.skin-yellow-light .content-header{background:transparent}.skin-yellow-light .wrapper,.skin-yellow-light .main-sidebar,.skin-yellow-light .left-side{background-color:#f9fafc}.skin-yellow-light .content-wrapper,.skin-yellow-light .main-footer{border-left:1px solid #d2d6de}.skin-yellow-light .user-panel>.info,.skin-yellow-light .user-panel>.info>a{color:#444}.skin-yellow-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-yellow-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-yellow-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-yellow-light .sidebar-menu>li:hover>a,.skin-yellow-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-yellow-light .sidebar-menu>li.active{border-left-color:#f39c12}.skin-yellow-light .sidebar-menu>li.active>a{font-weight:600}.skin-yellow-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-yellow-light .sidebar a{color:#444}.skin-yellow-light .sidebar a:hover{text-decoration:none}.skin-yellow-light .treeview-menu>li>a{color:#777}.skin-yellow-light .treeview-menu>li.active>a,.skin-yellow-light .treeview-menu>li>a:hover{color:#000}.skin-yellow-light .treeview-menu>li.active>a{font-weight:600}.skin-yellow-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-yellow-light .sidebar-form input[type="text"],.skin-yellow-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-yellow-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow-light .sidebar-form input[type="text"]:focus,.skin-yellow-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-yellow-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}.skin-purple .main-header .navbar{background-color:#605ca8}.skin-purple .main-header .navbar .nav>li>a{color:#fff}.skin-purple .main-header .navbar .nav>li>a:hover,.skin-purple .main-header .navbar .nav>li>a:active,.skin-purple .main-header .navbar .nav>li>a:focus,.skin-purple .main-header .navbar .nav .open>a,.skin-purple .main-header .navbar .nav .open>a:hover,.skin-purple .main-header .navbar .nav .open>a:focus,.skin-purple .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-purple .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple .main-header .logo{background-color:#555299;color:#fff;border-bottom:0 solid transparent}.skin-purple .main-header .logo:hover{background-color:#545096}.skin-purple .main-header li.user-header{background-color:#605ca8}.skin-purple .content-header{background:transparent}.skin-purple .wrapper,.skin-purple .main-sidebar,.skin-purple .left-side{background-color:#222d32}.skin-purple .user-panel>.info,.skin-purple .user-panel>.info>a{color:#fff}.skin-purple .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-purple .sidebar-menu>li>a{border-left:3px solid transparent}.skin-purple .sidebar-menu>li:hover>a,.skin-purple .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#605ca8}.skin-purple .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-purple .sidebar a{color:#b8c7ce}.skin-purple .sidebar a:hover{text-decoration:none}.skin-purple .treeview-menu>li>a{color:#8aa4af}.skin-purple .treeview-menu>li.active>a,.skin-purple .treeview-menu>li>a:hover{color:#fff}.skin-purple .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-purple .sidebar-form input[type="text"],.skin-purple .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-purple .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple .sidebar-form input[type="text"]:focus,.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-purple-light .main-header .navbar{background-color:#605ca8}.skin-purple-light .main-header .navbar .nav>li>a{color:#fff}.skin-purple-light .main-header .navbar .nav>li>a:hover,.skin-purple-light .main-header .navbar .nav>li>a:active,.skin-purple-light .main-header .navbar .nav>li>a:focus,.skin-purple-light .main-header .navbar .nav .open>a,.skin-purple-light .main-header .navbar .nav .open>a:hover,.skin-purple-light .main-header .navbar .nav .open>a:focus,.skin-purple-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-purple-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-purple-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple-light .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-purple-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple-light .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple-light .main-header .logo{background-color:#605ca8;color:#fff;border-bottom:0 solid transparent}.skin-purple-light .main-header .logo:hover{background-color:#5d59a6}.skin-purple-light .main-header li.user-header{background-color:#605ca8}.skin-purple-light .content-header{background:transparent}.skin-purple-light .wrapper,.skin-purple-light .main-sidebar,.skin-purple-light .left-side{background-color:#f9fafc}.skin-purple-light .content-wrapper,.skin-purple-light .main-footer{border-left:1px solid #d2d6de}.skin-purple-light .user-panel>.info,.skin-purple-light .user-panel>.info>a{color:#444}.skin-purple-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-purple-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-purple-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-purple-light .sidebar-menu>li:hover>a,.skin-purple-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-purple-light .sidebar-menu>li.active{border-left-color:#605ca8}.skin-purple-light .sidebar-menu>li.active>a{font-weight:600}.skin-purple-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-purple-light .sidebar a{color:#444}.skin-purple-light .sidebar a:hover{text-decoration:none}.skin-purple-light .treeview-menu>li>a{color:#777}.skin-purple-light .treeview-menu>li.active>a,.skin-purple-light .treeview-menu>li>a:hover{color:#000}.skin-purple-light .treeview-menu>li.active>a{font-weight:600}.skin-purple-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-purple-light .sidebar-form input[type="text"],.skin-purple-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px}.skin-purple-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple-light .sidebar-form input[type="text"]:focus,.skin-purple-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-purple-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}} \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/css/bootstrap.min.css b/renren-generator/src/main/resources/static/css/bootstrap.min.css new file mode 100644 index 0000000..ed3905e --- /dev/null +++ b/renren-generator/src/main/resources/static/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/css/font-awesome.min.css b/renren-generator/src/main/resources/static/css/font-awesome.min.css new file mode 100644 index 0000000..540440c --- /dev/null +++ b/renren-generator/src/main/resources/static/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/renren-generator/src/main/resources/static/css/main.css b/renren-generator/src/main/resources/static/css/main.css new file mode 100644 index 0000000..a6ed176 --- /dev/null +++ b/renren-generator/src/main/resources/static/css/main.css @@ -0,0 +1,54 @@ +html { overflow-x:hidden; } +.content-header { + position: relative; + padding: 0 0 3px 8px +} + +.content-header>.breadcrumb { + position: relative; + top: 0; + right: 0; + float: none; + margin-top: 0px; + padding-left: 10px; + background: #ecf0f5; +} + +.main-footer { + padding: 7px; + color: #444; + border-top: 1px solid #eee; +} + +[v-cloak] { + display: none; +} + +.grid-btn{ + margin-bottom:12px; +} +.grid-btn .btn{ + margin-right:10px; +} +.pointer{cursor: pointer;} + +.ml-10 { margin-left:0 !important; } +@media (min-width: 768px) { + .ml-10 { margin-left:10px !important; } + .col-sm-10 {width: 70%;padding-left: 0px;} + .col-sm-2 {width: 24%;} +} +tbody > tr > th {font-weight: normal; } +.panel .table { margin:0 0; } +.panel .pagination { margin:0; } +.panel-default>.panel-heading {background-color: #f5f5f5;} +.row{ + border-top: 1px solid #ddd; + margin:0; + padding:20px 2px 0px 2px; +} +.col-xs-6{padding-left: 0px;padding-right: 0px;} +.form-horizontal .form-group {margin-left:0px;margin-right:0px;} +.form-horizontal{ + width:550px;padding-top:20px; +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/favicon.ico b/renren-generator/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2bd581cea17fd10bf80730efcf0563e634494a91 GIT binary patch literal 4286 zcmd6rTTc@~6vxLWUw!hKM?Z!i0Bu2TsS-6cTx^U+gVA^?F$OhFG%>~~61Dn5)V9zS zY^l%`s1Q@d(qdYKrfW;@ug1sYITNQ@=mITfcWrYzvpZ+c?>{qVXLrijKKwQ{G5Ter z2N*lZ7(0Z9r`TaMI?q4Yw%y03kaEKVvYz zHV4wmIE+Mwq08G|!|3%{xo^2#hCsp(XZ^i3KK10uu`v^8RVo!wv-R8>^!s{LW1o<^ zz!iH3q@h?Uf^+F5P`rA$!spHMXbm@+O~UIXCtUh?0a`pqca1j~x&fI&hR0bLH$23(i+)GtZ*XhYj?5!6T=)jE_JGE==8Sn93wx{U=Lka_1hZ1p5uY(i%=*PxQ5vu zA=R;*_%8AGY%vSuUr*ddeCWOub2=P(vMK)k1qW{{l=5&jczIJ>BaGdAgR9e=lSfXU z?+oYAoac%;o^wO4vvHtXa`&Z2P$uFgRFcq=T+QLgD(XmvQ`C zbl2eg`l31p_riB{=hONsaxjrifJN%iRm08DwJM)<*ztL(^}VNzPiru7={>;{cQ^cw zpp3Pbx^?mtJpTNMKOgsUz4989@$cV8?>`LNf8jjveJGZ??>~vTWe=>|{u^_yy8liy Twto=+A|O-h(XuXhX=MKaRZyEC literal 0 HcmV?d00001 diff --git a/renren-generator/src/main/resources/static/fonts/FontAwesome.otf b/renren-generator/src/main/resources/static/fonts/FontAwesome.otf new file mode 100644 index 0000000000000000000000000000000000000000..401ec0f36e4f73b8efa40bd6f604fe80d286db70 GIT binary patch literal 134808 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 literal 0 HcmV?d00001 diff --git a/renren-generator/src/main/resources/static/fonts/fontawesome-webfont.eot b/renren-generator/src/main/resources/static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..e9f60ca953f93e35eab4108bd414bc02ddcf3928 GIT binary patch literal 165742 zcmd443w)Ht)jvM-T=tf|Uz5#kH`z;W1W0z103j^*Tev7F2#5hiQ9w~aka}5_DkxP1 zRJ3Y?7YePlysh?CD|XvjdsAv#YOS?>W2@EHO9NV8h3u2x_sp}KECIB>@9+Qn{FBV{ zJTr4<=FH5QnRCvZnOu5{#2&j@Vw_3r#2?PKa|-F4dtx{Ptp0P(#$Rn88poKQO<|X@ zOW8U$o^4<&*p=|D!J9EVI}`7V*m|~_En`<8B*M-{$Q6LOSfmND1Z!lia3ffVHQ_mu zwE*t)c_Na~v9UCh+1x2p=FeL7+|;L;bTeUAHg(eEDN-*};9m=WXwJOhO^lgVEPBX5Gh_bo8QSSFY{vM^4hsD-mzHX!X?>-tpg$&tfe27?V1mUAbb} z1dVewCjIN7C5$=lXROG% zX4%HIa)VTc_%^_YE?u@}#b58a4S8RL@|2s`UUucWZ{P9NJxp5Fi!#@Xx+(mZ+kdt3 zobw#*|6)Z(BxCGw^Gi+ncRvs|a|3xz=tRA9@HDV~1eqD)`^`KTPEg`UdXhq18})-@}JTHp30^)`L{?* z;c)alkYAc@67|W!7RDPu6Tsy@xJCK8{2T9-fJw6?@=A(w^}KCVjwlOd=JTO=3Zr+< zIdd?1zo-M^76}Jf!cpLfH`+2q=}d5id5XLcPw#xVocH5RVG7;@@%R>Sxpy8{(H9JH zY1V)?J1-AIeIxKhoG1%;AWq7C50ok3DSe?!Gatbry_zpS*VoS6`$~lK9E?(!mcrm1 z^cLZ1fmx5Ds`-ethCvMtDTz zMd=G1)gR$jic|1SaTLaL-{ePJOFkUs%j634IMp}dnR5yGMtsXmA$+JDyxRuSq*)bk zt3tSN2(J<@ooh3|!(R%VsE#5%U{m-mB7fcy&h(8kC(#>yA(JCmQ6|O1<=_U=0+$AY zC)@~M`UboR6Xm2?$e8Z$r#u8)TEP0~`viw@@+){#874R?kHRP|IU4&!?+9Cy52v^I zPV4Xd{9yc;)#l?0VS#6g@ z`#y))03Laq@^6Z#Z*uvzpl{$JzFJgn&xHlNBS|Eb!E@}~Z$^m!a9k34KX zT|VETZ;B_E$Ai8J#t5#kATCAUlqbr&P~-s)k^FfWyz}iK@`B$FI6L0u1uz5fgfqgU zRBmB>F8s_qp1HWm1!aXOEbpf`U?X|>{F`8Md500U3i;Mh9Kvbd(CeuC>077ww4g^h zKgM(A48W`XEDE~N*Th^NqP#S7&^w2Vpq+df2#@A*&4u~I+>t)9&GYcop9OtUo=;2d zGSq?IMBAYZffMC1v^|Z|AWdQ38UdJS4(H(nFI<|%=>0iAn3lvcSjIR(^7r7QuQI0a zm+@Z9QXmf!efG1**%Ryq_G-AQs-mi^*WO#v+tE9_cWLjXz1Q{L-uqzh z-Vb`UBlaT|M;ecG9GQJ&>5)s1TzBO5BM%;V{K#`h4juXPkq?e&N9{)|j&>ZKeRS#3 zOOIZ6^!B3<9)0}ib4L#y{qxZe{ss8}C5PC)Atkb2XK%PS)jPMht9Na0x_5hTckhAT zOz+FRJ-xk0*b(QE(2)^GQb*<<={mCZNczb3Bi%<19LXGc`AE-^-lOcO^Jw^J>ge2~ zT}Rg*O&{HUwEO6RqnV>GAMK$M`~TX%q<>-my#5LOBmex)pWgq|V@{jX>a;k`PLtE< zG&ohK;*_0|<6n-C93MK4I*vGc9shKE;CSEhp5tA|KOBE|yyJM=@i)g?jyD~Db^OKg zhNH*vXUCr$uRH$ec+K$#$E%LtJ6>`8&T-iBTicKH)SNMZS zB8UG!{1{Y=QL&oLMgLzR(}0Y>sN0TqgG|kLqv_VcVSLD)aJ?AC^D!bLa6K5Ut1)YA zghRXq;YBrYhrzOK23vXorq6v~v*CBb?*bYw$l-3J@cY5H}8Gr;t8{e8!J}L*5e>!hOQnM3g=8eoXDiYZBlmBW?=(Qvo;ib;hP4-|5>J zo6*MD%*UW90?aI=ncV;fJZB$fY|a73<^rd=!0(I%TsLE9TH#hRHV<&~b~82~@n<2= z1-*oTQL{zWh}4H zGjX>}SbW{R;(k^VBouiebp<&Q9S1P`GIlM(uLaz7TNt~37h`FJ-B1j-jj@}iF}B$Yhy1^cv|oM`3X|20-GXwq z0QapK#%@FUZ9ik|D}cWpad#li_7EK6?wrrq4l5kOc5H@2*p5ENc6Pxb%`OEl1=q{i zU1`Sdjxcu562^8fWbEEDi1(A=o?`5)DC_=i#vVX^45ZpSrpE35`g>WA+_QYDo!1%Byk?;4A*Y^%H_McC{^)mJp(mf6Mr$1rr8Klp< z@9$&m+0Bd{OfmMH!q^XxU*>tneq@E)#@LU6-}5Nz`DYpXi4*QA#$MRP*w045^)U8x zl=XAu_Y36n%QPIqUi^r$mjH7JWgdEmv0oiv>}BNj>jtO;GSSiGr=LO--M;f3$4%-kcdA5=kp1;?w1)iU%_3WyqWQmjf@AcVZ3xc<7I~# zFHgbYU4b-}3LN4>NEZft6=17@TlH$jBZ!NjjQC2%Yu;hJu9NWwZ@DynQp=tBj8Wjw$e9<5A{>pD{iW zZqogXPX_!HxT$LypN98z;4>ox_a@^r4>R7`&G@Wh#%HG(p9^;e{AczsK5r7^^FxfE z1>DZ=f&=UVl(8@Y2be_)+!n?cUjPUAC8+bcuQI+Aab3F@Uxu=lJpt$oQq38DE=X{7U3=m6P!eKVy6&>UK5q-?WYKFCon} zcwbuv_Xy+HBi;48;XYwJy_)eGknfFvzbOHS_{~WFRt)zJ zijpU?=0x zkwe%IkXL3J<39wBKYX6?A1iQgGX8uw<3E|t_zN{~?=k)}E8{7uHGX6%I@xLJ5o5hU3g}A@9GyXR4dV3$^??m7ZGyeD0jQ;~={sZ6d0>}3fa8JQ~ z#Q6Kj>z^jLM;Px_;9g|>2lp6?Oy32JW8UD|ZH#LugXW9=mzl&9Ov2uUBsVZgS;-{zFeKKwOfnbOFe$i&Nu~HMe}YLB^Wk1(Qs^2cg^_pF zV@!&4GARo9*fb`^0bBDClWMmysSaUvuQREB7n2(BZbV*M)y$0@8CXG!nX&m5FyO}f|^_bYrq)EtQ3jEW$ z;E;a$iwt`}|2xOlf`@fNIFLzjYz@1@vMcQB;TbKpR_b1>hK{W@uw#sVI6JqW86H;C ztQ;P%k-Nf8ey^cATop^SG>2V0mP~Z;=5SL5H#}UQ-NIABSS;9=rYBEjx70^!0%|%? z6H%vBBRb1si5UK{xwWyrI#6mdl~NhlB{DFSQ4f#HYnQ4Tr9_9++!S!BCwdbtt-PhV z2|9^MD=%7f(aK494ZCcz4t6dY`X;_62ywrIPovV+sT0pH?+{mwxjh%^> zh_?T`uiv2^KX}>z4HVY!Y%V1QDcBvi>!sD@MEbj99(bg@lcBxTD9~gYzfIm>7jFFl;^hEgOD8Clhu+6jw>0z&OhJ=2DoJ42R3QaA zWOOLCseE6;o!xG!?ra~f^>o~D+1yBE?qxT0^k{Eo?@YU;MW)Dk7u-Ja^-t=jry`Nm z^!iU;|I=I9eR|&CLf`eUDtM5Q2iZ}-MO8dOpsgMv)7Ge`r77T1(I!FduCuw%>+xyh zv~lQApLDjitE7#8{D!C9^9KL8O}^S6)E?BVMw_qP`rdoia-YG@KjOf%Qh4Bnt8Mcoi9h#JRYY3kEvn*UVbReO50BrmV+ z;MZw4c4)uX7XS38vL%mZ(`R5ww4GL|?R_+gqd5vmpyBRdmy(bdo1(0=sB8@yxdn)~lxbJjigu9=)pPhNBHJ@OCr@Hfy7 zMKpelG=3bck_~6$*c^5qw$ra?cd)OqZ$smlOvLJWm7$z_{bM*t_;dW+m52!n&yhSI z0)LYKbKpO(yrBb!r(;1ei=F17uvjq5XquDp?1L{4s1~Hu@I46id3j>UeJTcx0fQ!$ z&o9RBJJn}4D52n3P@|_Z2y%SzQ!WJ22E$LC;WNiX*{T?@;Pj!}DC|#~nZ>-HpIS<2 za>P22_kUiz%sLYqOLTT7B=H>lmeZ$;kr+*xoe54)>BRz1U!muO7@@$$G=552gn*!9 zJ(lYeq-%(OX#D?e|IqRz)>flsYTDXrc#58b-%`5Jmp#FEV%&+o&w?z>k%vUF^x&@! zd}aqf<-yN_(1OoX0~BNi5+XV}sW1Mo_rky5sw&#MPqeg*Iv+ow^-qi|g!>=1)d@|( zIJ=tJ4Yw%YfhiFbenxIIR1N1mmKeveFq!eFI?k+2%4<3`YlV3hM zS45R<;g^uVtW5iZbSGet@1^}8sBUEktA@_c>)?i}IE-EQTR@N-j%b9$Syc1{S3U?8e~d3B1?Lij0H27USiF&gR}A>wG-vBGIPuh*4ry;{Khxekv}wCTm%_>vhFZSJ)Pw2iv6Q4YVoQ`J2w?yCkiavVTWeVa)j|q=T9@J0pTtcQX!VHnIM6Al- z^*7Og!1y$xN4)5fYK&2X5x-Om4A;1k20|=O+$wl^1T}IRHkcq<^P$a{C0fAii(ypB z{ef1n(U1a&g|>5}zY?N{!tOqN_uYr3yPejjJ>KeR7IW!#ztw(g!*Hj~SpH|bkC%t5kd^Q2w*f{D8tJPwQ z++kT&2yEHVY_jXXBg!P7SUbSC;y1@rj$sqoMWF2=y$%ua1S%Nn_dvGwR*;O^!Fd?1 z8#WkKL1{>+GcdW?sX2^RC#k8D;~{~1M4#fpPxGDbOWPf?oRS^(Y!}arFj}-9Ta5B$ zZhP0#34P$Fx`;w}a*AU%t?#oPQ+U$umO}+(WIxS!wnBcQuM;%yiYhbKnNwXa7LiRjmf+(2(ZG}wiz%sgWJi>jgGIsPnZ=KfX?8mJ2^L!4-hBx#UR zZa((80+3k2t!n9h@La(dm&Qrs_teRTeB}Y= zShqm6zJdPGS+juA6^_Mu3_1sz1Hvx#*|M6pnqz`jk<&F@Wt;g%i&gunm7lM5)wE@q zvbn6Q=6IU;C_@UMWs|fmylAcBqr(MowarQT7@9BsXzyH534G z1e0`Rlnqb_RAIW{M7dQoxdg$ z;&VZRA?1jrgF9nN0lg?)7VU>c#YI}iVKVtMV&I^SUL2sA9Xn2<8mY@_)qZF;^OV!$ z;QVMjZTMUtC^eDXuo)DkX75sJ*#d6g{w?U1!Fbwid(nlSiF_z zStRqVrV`8MJBg{|ZM^Kzrps2`fI(Eq&qUZ%VCjWLQn)GthGkFz0LcT(tUy)_i~PWb ze1obC@Hu0-n}r4LO@8%lp3+uoAMDWnx#|WFhG&pQo@eXSCzjp(&Xl4$kfY60LiIx^ zs+SA=sm(K<-^V>WxOdf!NXC0qN&86q?xh#r;L)>)B|KXvOuO+4*98HO?4jfcxpk`^ zU^8+npM|PWn*7Nj9O_U%@pt)^gcu2m|17^}h}J6KWCJ>t zv@Qsc2z0711@V0%PDVqW?i)a)=GC>nC+Kx~*FeS}p5iNes=&dpY_lv9^<|K`GOJMG zE5^7&yqgjFK*qz6I-su3QFo4`PbRSbk|gNIa3+>jPUVH}5I6C)+!U&5lUe4HyYIe4 z>&a$lqL(n;XP)9F?USc6ZA6!;oE+i8ksYGTfe8;xbPFg9e&VVdrRpkO9Zch#cxJH7 z%@Bt~=_%2;shO9|R5K-|zrSznwM%ZBp3!<;&S0$4H~PJ&S3PrGtf}StbLZKDF_le= z9k)|^Do10}k~3$n&#EP*_H_-3h8^ZuQ2JXaU@zY|dW@$oQAY%Z@s0V8+F~YQ=#aqp z=je#~nV5}oI1J`wLIQ^&`Mj01oDZ;O`V>BvWCRJd%56g!((T@-{aY6fa;a0Vs+v@O z0IK2dXum&DKB?-ese^F~xB8#t6TFirdTy3(-MedKc;2cI&D}ztv4^I%ThCj* ziyQ90UpuyI`FYm%sUlWqP(!Qcg-7n%dk-&uY15{cw0HD+gbuz}CQP*u8*(+KCYFiz80m1pT=kmx0(q(xrCPMsUH1k{mefDSp) zD5G^q?m1N%Jbl&_iz65-uBs{~7YjNpQ%+H^=H7i%nHnwimHSGDPZ(Z;cWG1wcZw|v z%*juq&!(bo!`O7T>Wkon^QZ-rLvkd_^z#)5Hg zxufObryg!`lzZc#{xRRv6592P5fce0Hl-xEm^*nBcP$v z0`KR64y6=xK{a*oNxW9jv+9)$I9SxN-Oig_c%UK7hZDj_WEb$BDlO#*M?@b>eU7 zxN!%UE+w#Wg$bqFfc# zeDOpwnoY)%(93rx(=q9nQKg6?XKJZrRP#oo(u>h_l6NOMld)_IF( zs6M+iRmTC+ALc}C7V>JEuRjk9o)*YO8Y}oKQNl2t?D;qFLv4U`StSyoFzFYuq>i@C zEa1!N?B0BK0gjTwsL04McVmu=$6B!!-4bi1u_j7ZpCQm-l2u7AlYMmx zH!4a*@eEhENs{b-gUMy{c*AjMjcwAWGv@lW4YQtoQvvf*jQ2wL8+EGF4rQjAc;uiEzG%4uf z9wX{X3(U5*s$>6M z)n+q=_&#l6nEa|4ez8YOb9q{(?8h1|AYN<53x+g()8?U_N+)sEV;tdoV{pJ^DTD)ZvO|;^t&(V6L2z~TSiWu zI&#bLG#NGMHVY^mJXXH_jBGA?Np1q;)EYzS3U=1VKn3aXyU}xGihu`L8($R|e#HpJ zzo`QozgXO&25>bM*l>oHk|GV&2I+U-2>)u7C$^yP7gAuth~}8}eO^2>X_8+G@2GX0 zUG8;wZgm*=I4#ww{Ufg2!~-Uu*`{`!$+eE)in1}WPMJ%i|32CjmFLR8);bg^+jrF* zW0A!Zuas6whwVl!G+Vp(ysAHq9%glv8)6>Sr8w=pzPe1s`fRb9oO^yGOQW^-OZ=5? zNNaJk+iSAxa}{PtjC&tu_+{8J_cw=JiFhMqFC!}FHB@j}@Q$b&*h-^U)Y&U$fDWad zC!K&D&RZgww6M(~`@DA92;#vDM1_`->Ss*g8*57^PdIP-=;>u#;wD4g#4|T7ZytTY zx(Q8lO+5Ris0v-@GZXC@|&A*DPrZ51ZeSyziwc>%X>dNyCAL zOSDTJAwK7d2@UOGmtsjCPM9{#I9Gbb7#z25{*;Tyl-Zho(Oh~-u(5CLQl;2ot%#Nl z_cf{VEA=LuSylKv$-{%A=U+QBv0&8bP;vDOcU|zc3n!Nu{9=5j6^6DL&6tm-J4|~) z9#1w(@m3N|G3n9Xf)O<|NO+P)+F(TgqN3E#F8`eIrDZn0=@MQ%cDBb8e*D_eBUXH+ zOtn|s5j9y2W~uaQm*j{3fV=j|wxar?@^xjmPHKMYy0eTPkG*<=QA$Wf)g`tfRlZ0v ztEyRwH(8<%&+zbQ+pg>z^Ucf8Jj>x$N*h{buawh;61^S+&ZX>H^j?#nw!}!~35^Z# zqU|=INy-tBD+E^RCJdtvC_M2+Bx*2%C6nTfGS!1b*MJvhKZZPkBfkjIFf@kLBCdo) zszai4sxmBgklbZ>Iqddc=N%2_4$qxi==t>5E!Ll+-y(NJc+^l)uMgMZH+KM<|+cUS^t~AUy&z{UpW?AA~QO;;xntfuA^Rj7SU%j)& zVs~)K>u%=e(ooP|$In{9cdb}2l?KYZinZ8o+i;N-baM#CG$-JMDcX1$y9-L(TsuaT zfPY9MCb3xN8WGxNDB@4sjvZ10JTUS1Snvy5l9QPbZJ1#AG@_xCVXxndg&0Cz99x`Z zKvV%^1YbB2L)tU+ww(e6EZYzc6gI5g;!?*}TsL=hotb0Mow8kxW*HVdXfdVep4yL` zdfTcM*7nwv5)3M-)^@ASp~`(sR`IsMgXV>xPx0&5!lR8(L&vn@?_Oi2EXy)sj?Q8S$Mm zP{=PsbQ)rJtxy*+R9EqNek1fupF(7d1z|uHBZdEQMm`l!QnDTsJ_DX2E=_R?o*D5) z4}Rh2eEvVeTQ^UXfsDXgAf@6dtaXG>!t?(&-a~B^KF@z*dl$BLVOt|yVElz!`rm5n z&%<$O{7{?+>7|f%3ctTlD}Sc0Zs_hY;YO-&eOIT+Kh%FJdM|_@8b7qIL;aj#^MhF1 z(>x4_KPKYTl+AOj0Q$t3La4&;o`HP%m8bgb`*0vs83ZT@J#{j%7e8dKm;){k%rMw* zG9eKbw_mh1PHLUB$7VNcJ=oL;nV~#W;r|rv;ISD5+Q-FH5g~=&gD`RrnNm>lGJ1GE zw`K+PW!P*uxsEyAzhLvBOEUkj>)1sV6q-RhP*nGS(JD%Z$|wijTm)a5S+oj03MzBz zPjp$XjyM!3`cFtv`8wrA`EpL(8Soof9J(X7wr2l^Y-+>){TrmrhW&h}yVPonlai>; zrF!_zz4@5^8y@95z(7+GLY@+~o<>}!RDp|@N4vi4Y-r@AF@6Q7ET8d9j~&O$3l#Yuo`voKB12v8pK*p3sJO+k{- zak5sNppfOFju-S9tC#^&UI}&^S-3TB^fmi<0$e%==MK3AqBrn!K@ZCzuah-}pRZc{ z?&7p`mEU5_{>6x=RAFr4-F+FYOMN%GSL@mvX-UT3jRI;_TJH7}l*La_ztFn+GQ3;r zNk;eb?nh&>e?Z$I<$LDON!e1tJ26yLILq`~hFYrCA|rj2uGJHxzz@8b<} z&bETBnbLPG9E*iz!<03Ld4q;C140%fzRO5j*Ql#XY*C-ELCtp24zs*#$X0ZhlF~Qj zq$4Nq9U@=qSTzHghxD(IcI0@hO0e}l7_PKLX|J5jQe+67(8W~90a!?QdAYyLs6f^$ zgAUsZ6%aIOhqZ;;;WG@EpL1!Mxhc_XD!cTY%MEAnbR^8{!>s|QGte5Y=ivx6=T9Ei zP_M&x-e`XKwm+O(fpg~P{^7QV&DZPW)$j@GX#kClVjXN6u+n=I$K0{Y-O4?f;0vgV zY+%5cgK;dNK1}{#_x-Zyaw9sN`r9jST(^5&m&8IY?IBml#h0G3e?uSWfByzKHLe8) z9oCU{cfd~u97`w2ATe{wQPagk*)FX|S+YdySpplm-DSKB*|c>@nSp$=zj{v3WyAgw zqtk_K3c5J|0pC zSpww86>3JZSitYm_b*{%7cv?=elhCFy1v6m)^n?211803vG_;TRU3WPV`g7=>ywvsW6B76c-kXXYuS7~J+@Lc zSf%7^`HIJ4D|VX9{BlBG~IV;M->JId%#U?}jR@kQ&o5A3HyYDx}6Nc^pMjj0Jeun)M=&7-NLZ9@2 z)j60}@#z8oft^qhO`qgPG;Gf4Q@Zbq!Fx_DP1GkX<}_%EF`!5fg*xCsir}$yMH#85 zT3Y4bdV)bucC=X;w24>D>XjaA@K`En^++$6E!jmvauA$rc9F%b=P&f^I7M+{{--HM z0JXFl21+}*Oz8zr@T8JQp9Td0TZ7rr0+&rWePPKdaG}l-^)$@O*ON;2pkAjf4ZSg# zy{PLo>hhTUUK_q5L{o!vKb^7AIkbXB zm3BG{rbFE>fKfZsL4iKVYubQMO_AvYWH<3F_@;7*b}ss*4!r5a-5Mr{qoVbpXW1cja+YCd!nQ3xt*CEBq_FNhDc93rhj=>>F59=AN5 zoRmKmL))oDox0VF;gltwNSdcF9cb*OX3{Gx?X{Q-krC~b9}_3yG8Bn{`W6m}6YD#q zAkEzk)zB|ZA2Ao`dW^gC77j#kXk7>zOYg~2Y0NyG9@9L)X=yRL!=`tj7; z^S=K3l)dWTz%eniebMP!Z)q@7d(l_cR;2OvPv7I~Va{X>R@4XXh- zOMOMef=}m)U?`>^E`qUO(+Ng$xKwZ1|FQ|>X41&zvAf`(9 zj3GGCzGHqa8_lMGV+Q3A(d5seacFHJ92meB0vj+?SfQ~dL#3UE!1{}wjz|HPWCEHI zW{zYTeA(UwAEq6F%|@%!oD5ebM$D`kG45gkQ6COfjjk-==^@y6=Tp0-#~0px=I@H# z7Z|LQii;EBSfjse{lo}m?iuTG`$i6*F?L9m*kGMV_JUqsuT##HNJkrNL~cklwZK&3 zgesq4oycISoHuCg>Jo;0K(3&I(n-j7+uaf)NPK7+@p8+z!=r!xa45cmV`Mna1hT=i zAkgv-=xDHofR+dHn7FZvghtoxVqmi^U=Tk5i*(?UbiEGt9|mBN4tXfwT0b zIQSzTbod84Y<){2C!IJja=k65vqPM|!xFS?-HOK!3%&6=!T(Z$<>g6+rTpioPBf57 z$!8fVo=}&Z?KB-UB4$>vfxffiJ*^StPHhnl@7Fw@3-N|6BAyp|HhmV#(r=Ll2Y3af zNJ44J*!nZfs0Z5o%Qy|_7UzOtMt~9CA*sTy5=4c0Q9mP-JJ+p-7G&*PyD$6sj+4b>6a~%2eXf~A?KRzL4v_GQ!SRxsdZi`B(7Jx*fGf@DK z&P<|o9z*F!kX>I*;y78= z>JB#p1zld#NFeK3{?&UgU*1uzsxF7qYP34!>yr;jKktE5CNZ3N_W+965o=}3S?jx3 zv`#Wqn;l-4If#|AeD6_oY2Y||U?Fss}Sa>HvkP$9_KPcb_jB*Jc;M0XIE+qhbP$U2d z&;h?{>;H=Sp?W2>Uc{rF29ML>EiCy?fyim_mQtrgMA~^uv?&@WN@gUOPn(379I}U4Vg~Qo)jwJb7e_Pg^`Gmp+s5vF{tNzJVhBQ z$VB8M@`XJsXC!-){6wetDsTY94 G*yFsbY~cLNXLP73aA74Mq6M9f^&YV`isWW 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

5q!RY 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 + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/renren-generator/src/main/resources/static/fonts/fontawesome-webfont.ttf b/renren-generator/src/main/resources/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..35acda2fa1196aad98c2adf4378a7611dd713aa3 GIT binary patch literal 165548 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 z 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 d0mRO}xo^G_%I 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 SdSQM28?+M|D(2r_;{O0|uQ74} literal 0 HcmV?d00001 diff --git a/renren-generator/src/main/resources/static/fonts/fontawesome-webfont.woff2 b/renren-generator/src/main/resources/static/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4d13fc60404b91e398a37200c4a77b645cfd9586 GIT binary patch literal 77160 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 literal 0 HcmV?d00001 diff --git a/renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.eot b/renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.ttf b/renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.woff2 b/renren-generator/src/main/resources/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 zcmV(~K+nH-Pew8T0RR9107h&84*&oF0I^&E07eM_0Rl|`00000000000000000000 z0000#Mn+Uk92y`7U;vDA2m}!b3WBL5f#qcZHUcCAhI9*rFaQJ~1&1OBl~F%;WnyLq z8)b|&?3j;$^FW}&KmNW53flIFARDZ7_Wz%hpoWaWlgHTHEHf()GI0&dMi#DFPaEt6 zCO)z0v0~C~q&0zBj^;=tv8q{$8JxX)>_`b}WQGgXi46R*CHJ}6r+;}OrvwA{_SY+o zK)H-vy{l!P`+NG*`*x6^PGgHH4!dsolgU4RKj@I8Xz~F6o?quCX&=VQ$Q{w01;M0? zKe|5r<_7CD z=eO3*x!r$aX2iFh3;}xNfx0v;SwBfGG+@Z;->HhvqfF4r__4$mU>Dl_1w;-9`~5rF~@!3;r~xP-hZvOfOx)A z#>8O3N{L{naf215f>m=bzbp7_(ssu&cx)Qo-{)!)Yz3A@Z0uZaM2yJ8#OGlzm?JO5gbrj~@)NB4@?>KE(K-$w}{};@dKY#K3+Vi64S<@!Z{(I{7l=!p9 z&kjG^P~0f46i13(w!hEDJga;*Eb z`!n|++@H8VaKG<9>VDh(y89J#=;Z$ei=GnD5TesW#|Wf)^D+9NKN4J3H5PF_t=V+Z zdeo8*h9+8&Zfc?>>1|E4B7MAx)^uy$L>szyXre7W|81fjy+RZ1>Gd}@@${~PCOXo) z$#HZd3)V3@lNGG%(3PyIbvyJTOJAWcN@Uh!FqUkx^&BuAvc)G}0~SKI`8ZZXw$*xP zum-ZdtPciTAUn$XWb6vrS=JX~f5?M%9S(=QsdYP?K%Odn0S0-Ad<-tBtS3W06I^FK z8}d2eR_n!(uK~APZ-#tl@SycxkRJ@5wmypdWV{MFtYBUY#g-Vv?5AEBj1 z`$T^tRKca*sn7gt%s@XUD-t>bij-4q-ilku9^;QJ3Mpc`HJ_EX4TGGQ-Og)`c~qm51<|gp7D@ zp#>Grssv^#A)&M8>ulnDM_5t#Al`#jaFpZ<#YJ@>!a$w@kEZ1<@PGs#L~kxOSz7jj zEhb?;W)eS}0IQQuk4~JT30>4rFJ3!b+77}>$_>v#2FFEnN^%(ls*o80pv0Q>#t#%H z@`Yy-FXQ9ULKh{Up&oA_A4B!(x^9&>i`+T|eD!&QOLVd(_avv-bFX~4^>o{%mzzrg_i~SBnr%DeE|i+^}|8?kaV(Z32{`vA^l!sp15>Z72z52FgXf z^8ZITvJ9eXBT1~iQjW|Q`Fac^ak$^N-vI^*geh5|*CdMz;n16gV_zk|Z7q8tFfCvU zJK^Pptnn0Rc~egGIAK}uv99VZm2WLPezQQ5K<`f zg{8Ll|GioPYfNheMj-7-S87=w4N0WxHP`1V6Y)0M&SkYzVrwp>yfsEF7wj&T0!}dB z)R~gGfP9pOR;GY_e0~K^^oJ-3AT+m~?Al!{>>5gNe17?OWz)$)sMH*xuQiB>FT2{i zQ>6U_8}Ay~r4li;jzG+$&?S12{)+<*k9 z<^SX#xY|jvlvTxt(m~C7{y{3g>7TX#o2q$xQO|fc<%8rE@A3=UW(o?gVg?gDV!0q6O!{MlX$6-Bu_m&0ms66 znWS&zr{O_4O&{2uCLQvA?xC5vGZ}KV1v6)#oTewgIMSnBur0PtM0&{R5t#UEy3I9) z`LVP?3f;o}sz*7g5qdTxJl^gk3>;8%SOPH@B)rmFOJ)m6?PlYa$y=RX%;}KId{m9R#2=LNwosF@OTivgMqxpRGe}5=LtAn?VVl6VWCFLD z7l#^^H8jY~42hR)OoVF#YDW(md!g(&pJ;yMj|UBAQa}UH?ED@%ci=*(q~Opn>kE2Q z_4Kgf|0kEA6ary41A;)^Ku(*nirvP!Y>{FZYBLXLP6QL~vRL+uMlZ?jWukMV*(dsn zL~~KA@jU)(UeoOz^4Gkw{fJsYQ%|UA7i79qO5=DOPBcWlv%pK!A+)*F`3WJ}t9FU3 zXhC4xMV7Z%5RjDs0=&vC4WdvD?Zi5tg4@xg8-GLUI>N$N&3aS4bHrp%3_1u9wqL)i z)XQLsI&{Hd&bQE!3m&D0vd!4D`l1$rt_{3NS?~lj#|$GN5RmvP(j3hzJOk=+0B*2v z)Bw133RMUM%wu_+$vbzOy?yk#kvR?xGsg-ipX4wKyXqd zROKp5))>tNy$HByaEHK%$mqd>-{Yoj`oSBK;w>+eZ&TVcj^DyXjo{DDbZ>vS2cCWB z(6&~GZ}kUdN(*2-nI!hvbnVy@z2E#F394OZD&Jb04}`Tgaj?MoY?1`{ejE2iud51% zQ~J0sijw(hqr_Ckbj@pm$FAVASKY(D4BS0GYPkSMqSDONRaFH+O2+jL{hIltJSJT~e)TNDr(}=Xt7|UhcU9eoXl&QZRR<9WomW%&m)FT~j zTgGd3-j}Uk%CRD;$@X)NNV9+RJbifYu>yr{FkO;p>_&njI> zyBHh_72bW;8}oGeY0gpHOxiV597j7mY<#?WMmkf5x~Kfk*re(&tG_mX<3&2cON*2u%V29tsXUv{#-ijs2>EuNH-x3) zPBpi+V6gI=wn}u164_j8xi-y(B?Au2o;UO=r6&)i5S3Mx*)*{_;u}~i4dh$`VgUS- zMG6t*?DXDYX0D2Oj31MI!HF>|aG8rjrOPnxHu4wZl;!=NGjjDoBpXf?ntrwt^dqxm zs(lE@*QB3NH)!`rH)5kks-D89g@UX&@DU9jvrsY)aI=9b4nPy3bfdX_U;#?zsan{G>DKob2LnhCJv8o}duQK)qP{7iaaf2=K`a-VNcfC582d4a z>sBJA*%S|NEazDxXcGPW_uZ&d7xG`~JB!U>U(}acUSn=FqOA~(pn^!aMXRnqiL0;? zebEZYouRv}-0r;Dq&z9>s#Rt1HL`0p4bB)A&sMyn|rE_9nh z?NO*RrjET8D4s(-`nS{MrdYtv*kyCnJKbsftG2D#ia@;42!8xd?a3P(&Y?vCf9na< zQ&Ni*1Qel&Xq{Z?=%f0SRqQt5m|Myg+8T=GDc)@^};=tM>9IDr7hdvE9-M@@<0pqv45xZTeNecbL- zWFQt4t`9>j8~X%lz}%We>Kzh_=`XO}!;4!OWH?=p*DOs#Nt({k^IvtBEL~Qafn)I^ zm*k{y7_bIs9YE}0B6%r`EIUH8US+MGY!KQA1fi-jCx9*}oz2k1nBsXp;4K<_&SN}}w<)!EylI_)v7}3&c)V;Cfuj*eJ2yc8LK=vugqTL><#65r6%#2e| zdYzZ)9Uq7)A$ol&ynM!|RDHc_7?FlWqjW>8TIHc`jExt)f5W|;D%GC#$u!%B*S%Z0 zsj&;bIU2jrt_7%$=!h4Q29n*A^^AI8R|stsW%O@?i+pN0YOU`z;TVuPy!N#~F8Z29 zzZh1`FU(q31wa>kmw{$q=MY>XBprL<1)Py~5TW4mgY%rg$S=4C^0qr+*A^T)Q)Q-U zGgRb9%MdE-&i#X3xW=I`%xDzAG95!RG9)s?v_5+qx`7NdkQ)If5}BoEp~h}XoeK>kweAMxJ8tehagx~;Nr_WP?jXa zJ&j7%Ef3w*XWf?V*nR)|IOMrX;$*$e23m?QN` zk>sC^GE=h6?*Cr~596s_QE@>Nnr?{EU+_^G=LZr#V&0fEXQ3IWtrM{=t^qJ62Sp=e zrrc>bzX^6yFV!^v7;>J9>j;`qHDQ4uc92eVe6nO@c>H=ouLQot``E~KLNqMqJ7(G+?GWO9Ol+q$w z!^kMv!n{vF?RqLnxVk{a_Ar;^sw0@=+~6!4&;SCh^utT=I zo&$CwvhNOjQpenw2`5*a6Gos6cs~*TD`8H9P4=#jOU_`%L!W;$57NjN%4 z39(61ZC#s7^tv`_4j}wMRT9rgDo*XtZwN-L;Qc$6v8kKkhmRrxSDkUAzGPgJ?}~_t zkwoGS4=6lsD`=RL|8L3O9L()N)lmEn-M15fRC{dhZ}7eYV%O-R^gsAp{q4 z!C1}_T8gy^v@SZ5R&Li5JMJy+K8iZw3LOGA0pN1~y@w7RRl#F()ii6Y5mr~Mdy@Kz z@FT4cm^I&#Fu_9IX(HAFP{XLbRALqm&)>m_we>a`hfv?eE|t z?YdDp2yAhj-~vuw^wzVDuj%w?exOcOT(ls(F*ceCe(C5HlN{lcQ;}|mRPqFDqLEzw zR7ldY+M6xe$$qLwekmk{Z&5cME$gpC?-8)f0m$rqaS|mj9ATNJvvyCgs(f2{r;2E!oy$k5{jik#(;S>do<#m0wVcU<}>)VtYmF9O0%(C>GDzPgh6X z9OkQLMR~y7=|MtaU!LDPPY7O)L{X#SC+M|v^X2CZ?$GS>U_|aC(VA(mIvCNk+biD| zSpj>gd(v>_Cbq>~-x^Y3o|?eHmuC?E&z>;Ij`%{$Pm$hI}bl0Kd`9KD~AchY+goL1?igDxf$qxL9< z4sW@sD)nwWr`T>e2B8MQN|p*DVTT8)3(%AZ&D|@Zh6`cJFT4G^y6`(UdPLY-&bJYJ z*L06f2~BX9qX}u)nrpmHPG#La#tiZ23<>`R@u8k;ueM6 znuSTY7>XEc+I-(VvL?Y>)adHo(cZ;1I7QP^q%hu#M{BEd8&mG_!EWR7ZV_&EGO;d(hGGJzX|tqyYEg2-m0zLT}a{COi$9!?9yK zGN7&yP$a|0gL`dPUt=4d^}?zrLN?HfKP0_gdRvb}1D73Hx!tXq>7{DWPV;^X{-)cm zFa^H5oBDL3uLkaFDWgFF@HL6Bt+_^g~*o*t`Hgy3M?nHhWvTp^|AQDc9_H< zg>IaSMzd7c(Sey;1SespO=8YUUArZaCc~}}tZZX80w%)fNpMExki-qB+;8xVX@dr; z#L52S6*aM-_$P9xFuIui;dN#qZ_MYy^C^hrY;YAMg;K`!ZpKKFc z9feHsool)`tFSS}Su|cL0%F;h!lpR+ym|P>kE-O`3QnHbJ%gJ$dQ_HPTT~>6WNX41 zoDEUpX-g&Hh&GP3koF4##?q*MX1K`@=W6(Gxm1=2Tb{hn8{sJyhQBoq}S>bZT zisRz-xDBYoYxt6--g2M1yh{#QWFCISux}4==r|7+fYdS$%DZ zXVQu{yPO<)Hn=TK`E@;l!09aY{!TMbT)H-l!(l{0j=SEj@JwW0a_h-2F0MZNpyucb zPPb+4&j?a!6ZnPTB>$t`(XSf-}`&+#rI#`GB> zl=$3HORwccTnA2%>$Nmz)u7j%_ywoGri1UXVNRxSf(<@vDLKKxFo;5pTI$R~a|-sQ zd5Rfwj+$k1t0{J`qOL^q>vZUHc7a^`cKKVa{66z?wMuQAfdZBaVVv@-wamPmes$d! z>gv^xx<0jXOz;7HIQS z4RBIFD?7{o^IQ=sNQ-k!ao*+V*|-^I2=UF?{d>bE9avsWbAs{sRE-y`7r zxVAKA9amvo4T}ZAHSF-{y1GqUHlDp4DO9I3mz5h8n|}P-9nKD|$r9AS3gbF1AX=2B zyaK3TbKYqv%~JHKQH8v+%zQ8UVEGDZY|mb>Oe3JD_Z{+Pq%HB+J1s*y6JOlk`6~H) zKt)YMZ*RkbU!GPHzJltmW-=6zqO=5;S)jz{ zFSx?ryqSMxgx|Nhv3z#kFBTuTBHsViaOHs5e&vXZ@l@mVI37<+^KvTE51!pB4Tggq zz!NlRY2ZLno0&6bA|KHPYOMY;;LZG&_lzuLy{@i$&B(}_*~Zk2 z>bkQ7u&Ww%CFh{aqkT{HCbPbRX&EvPRp=}WKmyHc>S_-qbwAr0<20vEoJ(!?-ucjE zKQ+nSlRL^VnOX0h+WcjGb6WI(8;7bsMaHXDb6ynPoOXMlf9nLKre;w*#E_whR#5!! z!^%_+X3eJVKc$fMZP;+xP$~e(CIP1R&{2m+iTQhDoC8Yl@kLM=Wily_cu>7C1wjVU z-^~I0P06ZSNVaN~A`#cSBH2L&tk6R%dU1(u1XdAx;g+5S^Hn9-L$v@p7CCF&PqV{Z?R$}4EJi36+u2JP7l(@fYfP!=e#76LGy^f>~vs0%s*x@X8`|5 zGd6JOHsQ=feES4Vo8%1P_7F5qjiIm#oRT0kO1(?Z_Dk6oX&j=Xd8Klk(;gk3S(ZFnc^8Gc=d;8O-R9tlGyp=2I@1teAZpGWUi;}`n zbJOS_Z2L16nVtDnPpMn{+wR9&yU9~C<-ncppPee`>@1k7hTl5Fn_3_KzQ)u{iJPp3 z)df?Xo%9ta%(dp@DhKuQj4D8=_!*ra#Ib&OXKrsYvAG%H7Kq|43WbayvsbeeimSa= z8~{7ya9ZUAIgLLPeuNmSB&#-`Je0Lja)M$}I41KHb7dQq$wgwX+EElNxBgyyLbA2* z=c1VJR%EPJEw(7!UE?4w@94{pI3E%(acEYd8*Wmr^R7|IM2RZ-RVXSkXy-8$!(iB* zQA`qh2Ze!EY6}Zs7vRz&nr|L60NlIgnO3L*Yz2k2Ivfen?drnVzzu3)1V&-t5S~S? zw#=Sdh>K@2vA25su*@>npw&7A%|Uh9T1jR$mV*H@)pU0&2#Se`7iJlOr$mp79`DKM z5vr*XLrg7w6lc4&S{So1KGKBqcuJ!E|HVFB?vTOjQHi)g+FwJqX@Y3q(qa#6T@3{q zhc@2T-W}XD9x4u+LCdce$*}x!Sc#+rH-sCz6j}0EE`Tk*irUq)y^za`}^1gFnF)C!yf_l_}I<6qfbT$Gc&Eyr?!QwJR~RE4!gKVmqjbI+I^*^ z&hz^7r-dgm@Mbfc#{JTH&^6sJCZt-NTpChB^fzQ}?etydyf~+)!d%V$0faN(f`rJb zm_YaJZ@>Fg>Ay2&bzTx3w^u-lsulc{mX4-nH*A(32O&b^EWmSuk{#HJk}_ULC}SB(L7`YAs>opp9o5UcnB^kVB*rmW6{s0&~_>J!_#+cEWib@v-Ms`?!&=3fDot`oH9v&$f<52>{n2l* z1FRzJ#yQbTHO}}wt0!y8Eh-0*|Um3vjX-nWH>`JN5tWB_gnW%; zUJ0V?_a#+!=>ahhrbGvmvObe8=v1uI8#gNHJ#>RwxL>E^pT05Br8+$@a9aDC1~$@* zicSQCbQcr=DCHM*?G7Hsovk|{$3oIwvymi#YoXeVfWj{Gd#XmnDgzQPRUKNAAI44y z{1WG&rhIR4ipmvBmq$BZ*5tmPIZmhhWgq|TcuR{6lA)+vhj(cH`0;+B^72{&a7ff* zkrIo|pd-Yxm+VVptC@QNCDk0=Re%Sz%ta7y{5Dn9(EapBS0r zLbDKeZepar5%cAcb<^;m>1{QhMzRmRem=+0I3ERot-)gb`i|sII^A#^Gz+x>TW5A& z3PQcpM$lDy`zb%1yf!e8&_>D02RN950KzW>GN6n@2so&Wu09x@PB=&IkIf|zZ1W}P zAKf*&Mo5@@G=w&290aG1@3=IMCB^|G4L7*xn;r3v&HBrD4D)Zg+)f~Ls$7*P-^i#B z4X7ac=0&58j^@2EBZCs}YPe3rqgLAA1L3Y}o?}$%u~)7Rk=LLFbAdSy@-Uw6lv?0K z&P@@M`o2Rll3GoYjotf@WNNjHbe|R?IKVn*?Rzf9v9QoFMq)ODF~>L}26@z`KA82t z43e!^z&WGqAk$Ww8j6bc3$I|;5^BHwt`?e)zf|&+l#!8uJV_Cwy-n1yS0^Q{W*a8B zTzTYL>tt&I&9vzGQUrO?YIm6C1r>eyh|qw~-&;7s7u1achP$K3VnXd8sV8J7ZTxTh z5+^*J5%_#X)XL2@>h(Gmv$@)fZ@ikR$v(2Rax89xscFEi!3_;ORI0dBxw)S{r50qf zg&_a*>2Xe{s@)7OX9O!C?^6fD8tc3bQTq9}fxhbx2@QeaO9Ej+2m!u~+u%Q6?Tgz{ zjYS}bleKcVhW~1$?t*AO^p!=Xkkgwx6OTik*R3~yg^L`wUU9Dq#$Z*iW%?s6pO_f8 zJ8w#u#Eaw7=8n{zJ}C>w{enA6XYHfUf7h)!Qaev)?V=yW{b@-z`hAz;I7^|DoFChP z1aYQnkGauh*ps6x*_S77@z1wwGmF8ky9fMbM$dr*`vsot4uvqWn)0vTRwJqH#&D%g zL3(0dP>%Oj&vm5Re%>*4x|h1J2X*mK5BH1?Nx_#7( zepgF`+n)rHXj!RiipusEq!X81;QQBXlTvLDj=Qub(ha&D=BDx3@-V*d!D9PeXUY?l zwZ0<4=iY!sUj4G>zTS+eYX7knN-8Oynl=NdwHS*nSz_5}*5LQ@=?Yr?uj$`C1m2OR zK`f5SD2|;=BhU#AmaTKe9QaSHQ_DUj1*cUPa*JICFt1<&S3P3zsrs^yUE;tx=x^cmW!Jq!+hohv_B> zPDMT0D&08dC4x@cTD$o1$x%So1Ir(G3_AVQMvQ13un~sP(cEWi$2%5q93E7t{3VJf%K? zuwSyDke~7KuB2?*#DV8YzJw z&}SCDexnUPD!%4|y~7}VzvJ4ch)WT4%sw@ItwoNt(C*RP)h?&~^g##vnhR0!HvIYx z0td2yz9=>t3JNySl*TszmfH6`Ir;ft@RdWs3}!J88UE|gj_GMQ6$ZYphUL2~4OY7} zB*33_bjkRf_@l;Y!7MIdb~bVe;-m78Pz|pdy=O*3kjak63UnLt!{^!!Ljg0rJD3a~ z1Q;y5Z^MF<=Hr}rdoz>yRczx+p3RxxgJE2GX&Si)14B@2t21j4hnnP#U?T3g#+{W+Zb z5s^@>->~-}4|_*!5pIzMCEp|3+i1XKcfUxW`8|ezAh>y{WiRcjSG*asw6;Ef(k#>V ztguN?EGkV_mGFdq!n#W)<7E}1#EZN8O$O|}qdoE|7K?F4zo1jL-v}E8v?9qz(d$&2 zMwyK&xlC9rXo_2xw7Qe0caC?o?Pc*-QAOE!+UvRuKjG+;dk|jQhDDBe?`XT7Y5lte zqSu0t5`;>Wv%|nhj|ZiE^IqA_lZu7OWh!2Y(627zb=r7Ends}wVk7Q5o09a@ojhH7 zU0m&h*8+j4e|OqWyJ&B`V`y=>MVO;K9=hk^6EsmVAGkLT{oUtR{JqSRY{Qi{kKw1k z6s;0SMPJOLp!som|A`*q3t0wIj-=bG8a#MC)MHcMSQU98Juv$?$CvYX)(n`P^!`5| zv3q@@|G@6wMqh;d;m4qvdibx2Yjml}vG9mDv&!0ne02M#D`Bo}xIB0VWh8>>WtNZQ z$&ISlJX;*ORQIO;k62qA{^6P%3!Z=Y1EbmY02{w^yB$`;%!{kur&XTGDiO2cjA)lr zsY^XZWy^DSAaz;kZ_VG?uWnJR7qdN18$~)>(kOoybY0~QYu9||K#|$Mby{3GduV~N zk9H7$7=RSo+?CUYF502`b76ytBy}sFak&|HIwRvB=0D|S`c#QCJPq zP)uOWI)#(n&{6|C4A^G~%B~BY21aOMoz9RuuM`Ip%oBz+NoAlb7?#`E^}7xXo!4S? zFg8I~G%!@nXi8&aJSGFcZAxQf;0m}942=i#p-&teLvE{AKm7Sl2f}Io?!IqbC|J;h z`=5LFOnU5?^w~SV@YwNZx$k_(kLNxZDE z3cf08^-rIT_>A$}B%IJBPcN^)4;90BQtiEi!gT#+EqyAUZ|}*b_}R>SGloq&6?opL zuT_+lwQMgg6!Cso$BwUA;k-1NcrzyE>(_X$B0HocjY~=Pk~Q08+N}(|%HjO_i+*=o z%G6C6A30Ch<0UlG;Zdj@ed!rfUY_i9mYwK8(aYuzcUzlTJ1yPz|Bb-9b33A9zRhGl>Ny-Q#JAq-+qtI@B@&w z$;PJbyiW=!py@g2hAi0)U1v=;avka`gd@8LC4=BEbNqL&K^UAQ5%r95#x%^qRB%KLaqMnG|6xKAm}sx!Qwo}J=2C;NROi$mfADui4)y(3wVA3k~{j^_5%H)C6K zlYAm1eY**HZOj($)xfKIQFtIVw$4&yvz9>(Crs>Gh{ zya6-FG7Dgi92#K)64=9Csj5?Zqe~_9TwSI!2quAwa1w-*uC5!}xY`?tltb0Hq740< zsq2QelPveZ4chr$=~U3!+c&>xyfvA1`)owOqj=i4wjY=A1577Gwg&Ko7;?il9r|_* z8P&IDV_g2D{in5OLFxsO!kx3AhO$5aKeoM|!q|VokqMlYM@HtsRuMtBY%I35#5$+G zpp|JOeoj^U=95HLemB04Yqv{a8X<^K9G2`&ShM_6&Bi1n?o?@MXsDj9Z*A3>#XK%J zRc*&SlFl>l)9DyRQ{*%Z+^e1XpH?0@vhpXrnPPU*d%vOhKkimm-u3c%Q^v3RKp9kx@A2dS?QfS=iigGr7m><)YkV=%LA5h@Uj@9=~ABPMJ z1UE;F&;Ttg5Kc^Qy!1SuvbNEqdgu3*l`=>s5_}dUv$B%BJbMiWrrMm7OXOdi=GOmh zZBvXXK7VqO&zojI2Om9};zCB5i|<210I{iwiGznGCx=FT89=Ef)5!lB1cZ6lbzgDn07*he}G&w7m!;|E(L-?+cz@0<9ZI~LqYQE7>HnPA436}oeN2Y(VfG6 zxNZuMK3Crm^Z_AFeHc~CVRrSl0W^?+Gbteu1g8NGYa3(8f*P{(ZT>%!jtSl6WbYVv zmE(37t0C8vJ6O-5+o*lL9XRcFbd~GSBGbGh3~R!67g&l)7n!kJlWd)~TUyXus#!&G6sR%(l(h1$xyrR5j_jM1zj#giA&@(Xl26@n<9>folx!92bQ z24h570+<)4!$!IQ(5yOU|4_E6aN@4v0+{Kx~Z z;q7fp%0cHziuI%!kB~w}g9@V+1wDz0wFlzX2UOvOy|&;e;t!lAR8tV2KQHgtfk8Uf zw;rs!(4JPODERk4ckd5I2Vq|0rd@@Mwd8MID%0^fITjYIQom^q;qhP8@|eJx{?5xX zc1@Fj*kDknlk{c-rnCloQ3hGh7OU+@efO3>fkRMcM>J?AeVP& zlfzX%cdp=N+4S#E*%^=BQ+N`A7C}|k%$|QUn0yI6S3$MS-NjO!4hm55uyju)Q6e!} z*OVO@A#-mfC9Pha6ng((Xl^V7{d+&u+yx)_B1{~t7d5e8L^i4J>;x<7@5;+l7-Gge zf#9diXJ$&v^rbN5V(ee%q0xBMEgS6%qZm7hNUP%G;^J44I!BmI@M*+FWz0!+s;+iQ zU4CuI+27bvNK8v>?7PZnVxB=heJ&_ymE0nN^W#-rqB%+JXkYGDuRw>JM_LdtLkiq* z6%%3&^BX$jnM@2bjiGc-DymKly)wVkA-pq;jSWL#7_*moZZ4I|-N}o8SK?sIv)p|c zu~9-B%tMc=!)YMFp*SiC0>kfnH8+X5>;+FFVN{~a9YVdIg1uGkZ~kegFy{^PU(4{( z`CbY`XmVA3esai686Yw8djCEyF7`bfB^F1)nwv+AqYLZ&Zy=eFhYT2uMd@{sP_qS4 zbJ&>PxajjZt?&c<1^!T|pLHfX=E^FJ>-l_XCZzvRV%x}@u(FtF(mS+Umw$e+IA74e>gCdTqi;6&=euAIpxd=Y3I5xWR zBhGoT+T`V1@91OlQ}2YO*~P4ukd*TBBdt?Plt)_ou6Y@Db`ss+Q~A-48s>?eaJYA2 zRGOa8^~Em}EFTmKIVVbMb|ob)hJJ7ITg>yHAn2i|{2ZJU!cwt9YNDT0=*WO7Bq#Xj zg@FjEaKoolrF8%c;49|`IT&25?O$dq8kp3#la9&6aH z6G|{>^C(>yP7#Dr$aeFyS0Ai_$ILhL43#*mgEl(c*4?Ae;tRL&S7Vc}Szl>B`mBuI zB9Y%xp%CZwlH!3V(`6W4-ZuETssvI&B~_O;CbULfl)X1V%(H7VSPf`_Ka9ak@8A=z z1l|B1QKT}NLI`WVTRd;2En5u{0CRqy9PTi$ja^inu){LJ&E&6W%JJPw#&PaTxpt?k zpC~gjN*22Q8tpGHR|tg~ye#9a8N<%odhZJnk7Oh=(PKfhYfzLAxdE36r<6a?A;rO&ELp_Y?8Pdw(PT^Fxn!eG_|LEbSYoBrsBA|6Fgr zt5LntyusI{Q2fdy=>ditS;}^B;I2MD4=(>7fWt0Jp~y=?VvfvzHvQhj6dyIef46J$ zl4Xu7U9v_NJV?uBBC0!kcTS0UcrV7+@~is?Fi+jrr@l3XwD|uG zr26jUWiv>Ju48Y^#qn7r9mwIH-Pv6Y|V|V-GZ&+&gQ?S?-`&ts{@5GXPqbmyZjUACC&oVXfNwUX0}ba(v978 zp8z!v9~8Zx8qB@7>oFPDm^iR@+yw`79YF)w^OHB_N;&&x7c3l^3!)IY#)}x)@D(iNaOm9 zC=^*!{`7={3*S=%iU=KsPXh=DDZcc``Ss>057i{pdW8M@4q+Ba@Tt%OytH!4>rbIbQw^-pR zGGYNPzw@n=PV@)b7yVbFr;glF*Qq3>F9oBN5PUXt!?2mdGcpv^o1?Thp`jP10G2Yi z(c93td3F3SW!Le5DUwdub!aDKoVLU6g!O?Ret21l$qOC;kdd@L#M&baVu&JZGt&<6 z!VCkvgRaav6QDW2x}tUy4~Y5(B+#Ej-8vM?DM-1?J_*&PntI3E96M!`WL#<&Z5n2u zo`P!~vBT$YOT~gU9#PB)%JZ zcd_u=m^LYzC!pH#W`yA1!(fA;D~b zG#73@l)NNd;n#XrKXZEfab;@kQRnOFU2Th-1m<4mJzlj9b3pv-GF$elX7ib9!uILM_$ke zHIGB*&=5=;ynQA{y7H93%i^d)T}y@(p>8vVhJ4L)M{0Q*@D^+SPp`EW+G6E%+`Z;u zS3goV@Dic7vc5`?!pCN44Ts@*{)zwy)9?B||AM{zKlN4T}qQRL2 zgv+{K8bv7w)#xge16;kI1fU87!W4pX)N&|cq8&i^1r`W|Hg4366r(?-ecEJ9u&Eaw zrhyikXQB>C9d>cpPGiu=VU3Z-u4|0V_iap!_J3o+K_R5EXk@sfu~zHwwYkpncVh!R zqNe7Cmf_|Wmeq4#(mIO&(wCK@b4(x0?W1Qtk(`$?+$uCJCGZm_%k?l32vuShgDFMa ztc`{$8DhB9)&?~(m&EUc=LzI1=qo#zjy#2{hLT_*aj<618qQ7mD#k2ZFGou&69;=2 z1j7=Su8k}{L*h&mfs7jg^PN&9C1Z@U!p6gXk&-7xM~{X`nqH#aGO`;Xy_zbz^rYacIq0AH%4!Oh93TzJ820%ur)8OyeS@K?sF1V(iFO z37Nnqj1z#1{|v7=_CX`lQA|$<1gtuNMHGNJYp1D_k;WQk-b+T6VmUK(x=bWviOZ~T z|4e%SpuaWLWD?qN2%`S*`P;BQBw(B__wTD6epvGdJ+>DBq2oVlf&F*lz+#avb4)3P1c^Mf#olQheVvZ|Z5 z>xXfgmv!5Z^SYn+_x}K5B%G^sRwiez&z9|f!E!#oJlT2kCOV0000$L_|bHBqAarB4TD{W@grX1CUr72@caw0faEd7-K|4L_|cawbojjHdpd6 zI6~Iv5J?-Q4*&oF000000FV;^004t70Z6Qk1Xl{X9oJ{sRC2(cs?- literal 0 HcmV?d00001 diff --git a/renren-generator/src/main/resources/static/js/common.js b/renren-generator/src/main/resources/static/js/common.js new file mode 100644 index 0000000..2594d4c --- /dev/null +++ b/renren-generator/src/main/resources/static/js/common.js @@ -0,0 +1,83 @@ +//jqGrid的配置信息 +$.jgrid.defaults.width = 1000; +$.jgrid.defaults.responsive = true; +$.jgrid.defaults.styleUI = 'Bootstrap'; + +//工具集合Tools +window.T = {}; + +// 获取请求参数 +// 使用示例 +// location.href = http://localhost:8080/index.html?id=123 +// T.p('id') --> 123; +var url = function(name) { + var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); + var r = window.location.search.substr(1).match(reg); + if(r!=null)return unescape(r[2]); return null; +}; +T.p = url; + +//全局配置 +$.ajaxSetup({ + dataType: "json", + contentType: "application/json", + cache: false +}); + +function hasPermission(permission) { + if (window.parent.permissions.indexOf(permission) > -1) { + return true; + } else { + return false; + } +} + +//重写alert +window.alert = function(msg, callback){ + parent.layer.alert(msg, function(index){ + parent.layer.close(index); + if(typeof(callback) === "function"){ + callback("ok"); + } + }); +} + +//重写confirm式样框 +window.confirm = function(msg, callback){ + parent.layer.confirm(msg, {btn: ['确定','取消']}, + function(){//确定事件 + if(typeof(callback) === "function"){ + callback("ok"); + } + }); +} + +//选择一条记录 +function getSelectedRow() { + var grid = $("#jqGrid"); + var rowKey = grid.getGridParam("selrow"); + if(!rowKey){ + alert("请选择一条记录"); + return ; + } + + var selectedIDs = grid.getGridParam("selarrrow"); + if(selectedIDs.length > 1){ + alert("只能选择一条记录"); + return ; + } + + return selectedIDs[0]; +} + +//选择多条记录 +function getSelectedRows() { + var grid = $("#jqGrid"); + var rowKey = grid.getGridParam("selrow"); + if(!rowKey){ + alert("请选择一条记录"); + return ; + } + + return grid.getGridParam("selarrrow"); +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/js/generator.js b/renren-generator/src/main/resources/static/js/generator.js new file mode 100644 index 0000000..f19a8f2 --- /dev/null +++ b/renren-generator/src/main/resources/static/js/generator.js @@ -0,0 +1,60 @@ +$(function () { + $("#jqGrid").jqGrid({ + url: 'sys/generator/list', + datatype: "json", + colModel: [ + { label: '表名', name: 'tableName', width: 100, key: true }, + { label: '表备注', name: 'tableComment', width: 100 }, + { label: '创建时间', name: 'createTime', width: 100 } + ], + viewrecords: true, + height: 385, + rowNum: 10, + rowList : [10,30,50,100,200], + rownumbers: true, + rownumWidth: 25, + autowidth:true, + multiselect: true, + pager: "#jqGridPager", + jsonReader : { + root: "page.list", + page: "page.currPage", + total: "page.totalPage", + records: "page.totalCount" + }, + prmNames : { + page:"page", + rows:"limit", + order: "order" + }, + gridComplete:function(){ + //隐藏grid底部滚动条 + $("#jqGrid").closest(".ui-jqgrid-bdiv").css({ "overflow-x" : "hidden" }); + } + }); +}); + +var vm = new Vue({ + el:'#rrapp', + data:{ + q:{ + tableName: null + } + }, + methods: { + query: function () { + $("#jqGrid").jqGrid('setGridParam',{ + postData:{'tableName': vm.q.tableName}, + page:1 + }).trigger("reloadGrid"); + }, + generator: function() { + var tableNames = getSelectedRows(); + if(tableNames == null){ + return ; + } + location.href = "sys/generator/code?tables=" + tableNames.join(); + } + } +}); + diff --git a/renren-generator/src/main/resources/static/js/index.js b/renren-generator/src/main/resources/static/js/index.js new file mode 100644 index 0000000..3a8d122 --- /dev/null +++ b/renren-generator/src/main/resources/static/js/index.js @@ -0,0 +1,52 @@ +//iframe自适应 +$(window).on('resize', function() { + var $content = $('.content'); + $content.height($(this).height() - 120); + $content.find('iframe').each(function() { + $(this).height($content.height()); + }); +}).resize(); + + +var vm = new Vue({ + el:'#rrapp', + data:{ + main:"main.html", + navTitle:"欢迎页" + }, + methods: { + donate: function () { + layer.open({ + type: 2, + title: false, + area: ['806px', '467px'], + closeBtn: 1, + shadeClose: false, + content: ['http://cdn.renren.io/donate.jpg', 'no'] + }); + } + } +}); + +//路由 +var router = new Router(); +var menus = ["main.html","generator.html"]; +routerList(router, menus); +router.start(); + +function routerList(router, menus){ + for(var index in menus){ + router.add('#'+menus[index], function() { + var url = window.location.hash; + + //替换iframe的url + vm.main = url.replace('#', ''); + + //导航菜单展开 + $(".treeview-menu li").removeClass("active"); + $("a[href='"+url+"']").parents("li").addClass("active"); + + vm.navTitle = $("a[href='"+url+"']").text(); + }); + } +} diff --git a/renren-generator/src/main/resources/static/libs/app.js b/renren-generator/src/main/resources/static/libs/app.js new file mode 100644 index 0000000..bd5ecd2 --- /dev/null +++ b/renren-generator/src/main/resources/static/libs/app.js @@ -0,0 +1,763 @@ +/*! AdminLTE app.js + * ================ + * Main JS application file for AdminLTE v2. This file + * should be included in all pages. It controls some layout + * options and implements exclusive AdminLTE plugins. + * + * @Author Almsaeed Studio + * @Support + * @Email + * @version 2.3.7 + * @license MIT + */ + +//Make sure jQuery has been loaded before app.js +if (typeof jQuery === "undefined") { + throw new Error("AdminLTE requires jQuery"); +} + +/* AdminLTE + * + * @type Object + * @description $.AdminLTE is the main object for the template's app. + * It's used for implementing functions and options related + * to the template. Keeping everything wrapped in an object + * prevents conflict with other plugins and is a better + * way to organize our code. + */ +$.AdminLTE = {}; + +/* -------------------- + * - AdminLTE Options - + * -------------------- + * Modify these options to suit your implementation + */ +$.AdminLTE.options = { + //Add slimscroll to navbar menus + //This requires you to load the slimscroll plugin + //in every page before app.js + navbarMenuSlimscroll: true, + navbarMenuSlimscrollWidth: "3px", //The width of the scroll bar + navbarMenuHeight: "200px", //The height of the inner menu + //General animation speed for JS animated elements such as box collapse/expand and + //sidebar treeview slide up/down. This options accepts an integer as milliseconds, + //'fast', 'normal', or 'slow' + animationSpeed: 'fast', + //Sidebar push menu toggle button selector + sidebarToggleSelector: "[data-toggle='offcanvas']", + //Activate sidebar push menu + sidebarPushMenu: true, + //Activate sidebar slimscroll if the fixed layout is set (requires SlimScroll Plugin) + sidebarSlimScroll: true, + //Enable sidebar expand on hover effect for sidebar mini + //This option is forced to true if both the fixed layout and sidebar mini + //are used together + sidebarExpandOnHover: false, + //BoxRefresh Plugin + enableBoxRefresh: true, + //Bootstrap.js tooltip + enableBSToppltip: true, + BSTooltipSelector: "[data-toggle='tooltip']", + //Enable Fast Click. Fastclick.js creates a more + //native touch experience with touch devices. If you + //choose to enable the plugin, make sure you load the script + //before AdminLTE's app.js + enableFastclick: false, + //Control Sidebar Options + enableControlSidebar: true, + controlSidebarOptions: { + //Which button should trigger the open/close event + toggleBtnSelector: "[data-toggle='control-sidebar']", + //The sidebar selector + selector: ".control-sidebar", + //Enable slide over content + slide: true + }, + //Box Widget Plugin. Enable this plugin + //to allow boxes to be collapsed and/or removed + enableBoxWidget: true, + //Box Widget plugin options + boxWidgetOptions: { + boxWidgetIcons: { + //Collapse icon + collapse: 'fa-minus', + //Open icon + open: 'fa-plus', + //Remove icon + remove: 'fa-times' + }, + boxWidgetSelectors: { + //Remove button selector + remove: '[data-widget="remove"]', + //Collapse button selector + collapse: '[data-widget="collapse"]' + } + }, + //Direct Chat plugin options + directChat: { + //Enable direct chat by default + enable: true, + //The button to open and close the chat contacts pane + contactToggleSelector: '[data-widget="chat-pane-toggle"]' + }, + //Define the set of colors to use globally around the website + colors: { + lightBlue: "#3c8dbc", + red: "#f56954", + green: "#00a65a", + aqua: "#00c0ef", + yellow: "#f39c12", + blue: "#0073b7", + navy: "#001F3F", + teal: "#39CCCC", + olive: "#3D9970", + lime: "#01FF70", + orange: "#FF851B", + fuchsia: "#F012BE", + purple: "#8E24AA", + maroon: "#D81B60", + black: "#222222", + gray: "#d2d6de" + }, + //The standard screen sizes that bootstrap uses. + //If you change these in the variables.less file, change + //them here too. + screenSizes: { + xs: 480, + sm: 768, + md: 992, + lg: 1200 + } +}; + +/* ------------------ + * - Implementation - + * ------------------ + * The next block of code implements AdminLTE's + * functions and plugins as specified by the + * options above. + */ +$(function () { + "use strict"; + + //Fix for IE page transitions + $("body").removeClass("hold-transition"); + + //Extend options if external options exist + if (typeof AdminLTEOptions !== "undefined") { + $.extend(true, + $.AdminLTE.options, + AdminLTEOptions); + } + + //Easy access to options + var o = $.AdminLTE.options; + + //Set up the object + _init(); + + //Activate the layout maker + $.AdminLTE.layout.activate(); + + //Enable sidebar tree view controls + $.AdminLTE.tree('.sidebar'); + + //Enable control sidebar + if (o.enableControlSidebar) { + $.AdminLTE.controlSidebar.activate(); + } + + //Add slimscroll to navbar dropdown + if (o.navbarMenuSlimscroll && typeof $.fn.slimscroll != 'undefined') { + $(".navbar .menu").slimscroll({ + height: o.navbarMenuHeight, + alwaysVisible: false, + size: o.navbarMenuSlimscrollWidth + }).css("width", "100%"); + } + + //Activate sidebar push menu + if (o.sidebarPushMenu) { + $.AdminLTE.pushMenu.activate(o.sidebarToggleSelector); + } + + //Activate Bootstrap tooltip + if (o.enableBSToppltip) { + $('body').tooltip({ + selector: o.BSTooltipSelector + }); + } + + //Activate box widget + if (o.enableBoxWidget) { + $.AdminLTE.boxWidget.activate(); + } + + //Activate fast click + if (o.enableFastclick && typeof FastClick != 'undefined') { + FastClick.attach(document.body); + } + + //Activate direct chat widget + if (o.directChat.enable) { + $(document).on('click', o.directChat.contactToggleSelector, function () { + var box = $(this).parents('.direct-chat').first(); + box.toggleClass('direct-chat-contacts-open'); + }); + } + + /* + * INITIALIZE BUTTON TOGGLE + * ------------------------ + */ + $('.btn-group[data-toggle="btn-toggle"]').each(function () { + var group = $(this); + $(this).find(".btn").on('click', function (e) { + group.find(".btn.active").removeClass("active"); + $(this).addClass("active"); + e.preventDefault(); + }); + + }); +}); + +/* ---------------------------------- + * - Initialize the AdminLTE Object - + * ---------------------------------- + * All AdminLTE functions are implemented below. + */ +function _init() { + 'use strict'; + /* Layout + * ====== + * Fixes the layout height in case min-height fails. + * + * @type Object + * @usage $.AdminLTE.layout.activate() + * $.AdminLTE.layout.fix() + * $.AdminLTE.layout.fixSidebar() + */ + $.AdminLTE.layout = { + activate: function () { + var _this = this; + _this.fix(); + _this.fixSidebar(); + $(window, ".wrapper").resize(function () { + _this.fix(); + _this.fixSidebar(); + }); + }, + fix: function () { + //Get window height and the wrapper height + var neg = $('.main-header').outerHeight() + $('.main-footer').outerHeight(); + var window_height = $(window).height(); + var sidebar_height = $(".sidebar").height(); + //Set the min-height of the content and sidebar based on the + //the height of the document. + if ($("body").hasClass("fixed")) { + $(".content-wrapper, .right-side").css('min-height', window_height - $('.main-footer').outerHeight()); + } else { + var postSetWidth; + if (window_height >= sidebar_height) { + $(".content-wrapper, .right-side").css('min-height', window_height - neg); + postSetWidth = window_height - neg; + } else { + $(".content-wrapper, .right-side").css('min-height', sidebar_height); + postSetWidth = sidebar_height; + } + + //Fix for the control sidebar height + var controlSidebar = $($.AdminLTE.options.controlSidebarOptions.selector); + if (typeof controlSidebar !== "undefined") { + if (controlSidebar.height() > postSetWidth) + $(".content-wrapper, .right-side").css('min-height', controlSidebar.height()); + } + + } + }, + fixSidebar: function () { + //Make sure the body tag has the .fixed class + if (!$("body").hasClass("fixed")) { + if (typeof $.fn.slimScroll != 'undefined') { + $(".sidebar").slimScroll({destroy: true}).height("auto"); + } + return; + } else if (typeof $.fn.slimScroll == 'undefined' && window.console) { + window.console.error("Error: the fixed layout requires the slimscroll plugin!"); + } + //Enable slimscroll for fixed layout + if ($.AdminLTE.options.sidebarSlimScroll) { + if (typeof $.fn.slimScroll != 'undefined') { + //Destroy if it exists + $(".sidebar").slimScroll({destroy: true}).height("auto"); + //Add slimscroll + $(".sidebar").slimscroll({ + height: ($(window).height() - $(".main-header").height()) + "px", + color: "rgba(0,0,0,0.2)", + size: "3px" + }); + } + } + } + }; + + /* PushMenu() + * ========== + * Adds the push menu functionality to the sidebar. + * + * @type Function + * @usage: $.AdminLTE.pushMenu("[data-toggle='offcanvas']") + */ + $.AdminLTE.pushMenu = { + activate: function (toggleBtn) { + //Get the screen sizes + var screenSizes = $.AdminLTE.options.screenSizes; + + //Enable sidebar toggle + $(document).on('click', toggleBtn, function (e) { + e.preventDefault(); + + //Enable sidebar push menu + if ($(window).width() > (screenSizes.sm - 1)) { + if ($("body").hasClass('sidebar-collapse')) { + $("body").removeClass('sidebar-collapse').trigger('expanded.pushMenu'); + } else { + $("body").addClass('sidebar-collapse').trigger('collapsed.pushMenu'); + } + } + //Handle sidebar push menu for small screens + else { + if ($("body").hasClass('sidebar-open')) { + $("body").removeClass('sidebar-open').removeClass('sidebar-collapse').trigger('collapsed.pushMenu'); + } else { + $("body").addClass('sidebar-open').trigger('expanded.pushMenu'); + } + } + }); + + $(".content-wrapper").click(function () { + //Enable hide menu when clicking on the content-wrapper on small screens + if ($(window).width() <= (screenSizes.sm - 1) && $("body").hasClass("sidebar-open")) { + $("body").removeClass('sidebar-open'); + } + }); + + //Enable expand on hover for sidebar mini + if ($.AdminLTE.options.sidebarExpandOnHover + || ($('body').hasClass('fixed') + && $('body').hasClass('sidebar-mini'))) { + this.expandOnHover(); + } + }, + expandOnHover: function () { + var _this = this; + var screenWidth = $.AdminLTE.options.screenSizes.sm - 1; + //Expand sidebar on hover + $('.main-sidebar').hover(function () { + if ($('body').hasClass('sidebar-mini') + && $("body").hasClass('sidebar-collapse') + && $(window).width() > screenWidth) { + _this.expand(); + } + }, function () { + if ($('body').hasClass('sidebar-mini') + && $('body').hasClass('sidebar-expanded-on-hover') + && $(window).width() > screenWidth) { + _this.collapse(); + } + }); + }, + expand: function () { + $("body").removeClass('sidebar-collapse').addClass('sidebar-expanded-on-hover'); + }, + collapse: function () { + if ($('body').hasClass('sidebar-expanded-on-hover')) { + $('body').removeClass('sidebar-expanded-on-hover').addClass('sidebar-collapse'); + } + } + }; + + /* Tree() + * ====== + * Converts the sidebar into a multilevel + * tree view menu. + * + * @type Function + * @Usage: $.AdminLTE.tree('.sidebar') + */ + $.AdminLTE.tree = function (menu) { + var _this = this; + var animationSpeed = $.AdminLTE.options.animationSpeed; + $(document).off('click', menu + ' li a') + .on('click', menu + ' li a', function (e) { + //Get the clicked link and the next element + var $this = $(this); + var checkElement = $this.next(); + + //Check if the next element is a menu and is visible + if ((checkElement.is('.treeview-menu')) && (checkElement.is(':visible')) && (!$('body').hasClass('sidebar-collapse'))) { + //Close the menu + checkElement.slideUp(animationSpeed, function () { + checkElement.removeClass('menu-open'); + //Fix the layout in case the sidebar stretches over the height of the window + //_this.layout.fix(); + }); + checkElement.parent("li").removeClass("active"); + } + //If the menu is not visible + else if ((checkElement.is('.treeview-menu')) && (!checkElement.is(':visible'))) { + //Get the parent menu + var parent = $this.parents('ul').first(); + //Close all open menus within the parent + var ul = parent.find('ul:visible').slideUp(animationSpeed); + //Remove the menu-open class from the parent + ul.removeClass('menu-open'); + //Get the parent li + var parent_li = $this.parent("li"); + + //Open the target menu and add the menu-open class + checkElement.slideDown(animationSpeed, function () { + //Add the class active to the parent li + checkElement.addClass('menu-open'); + parent.find('li.active').removeClass('active'); + parent_li.addClass('active'); + //Fix the layout in case the sidebar stretches over the height of the window + _this.layout.fix(); + }); + } + //if this isn't a link, prevent the page from being redirected + if (checkElement.is('.treeview-menu')) { + e.preventDefault(); + } + }); + }; + + /* ControlSidebar + * ============== + * Adds functionality to the right sidebar + * + * @type Object + * @usage $.AdminLTE.controlSidebar.activate(options) + */ + $.AdminLTE.controlSidebar = { + //instantiate the object + activate: function () { + //Get the object + var _this = this; + //Update options + var o = $.AdminLTE.options.controlSidebarOptions; + //Get the sidebar + var sidebar = $(o.selector); + //The toggle button + var btn = $(o.toggleBtnSelector); + + //Listen to the click event + btn.on('click', function (e) { + e.preventDefault(); + //If the sidebar is not open + if (!sidebar.hasClass('control-sidebar-open') + && !$('body').hasClass('control-sidebar-open')) { + //Open the sidebar + _this.open(sidebar, o.slide); + } else { + _this.close(sidebar, o.slide); + } + }); + + //If the body has a boxed layout, fix the sidebar bg position + var bg = $(".control-sidebar-bg"); + _this._fix(bg); + + //If the body has a fixed layout, make the control sidebar fixed + if ($('body').hasClass('fixed')) { + _this._fixForFixed(sidebar); + } else { + //If the content height is less than the sidebar's height, force max height + if ($('.content-wrapper, .right-side').height() < sidebar.height()) { + _this._fixForContent(sidebar); + } + } + }, + //Open the control sidebar + open: function (sidebar, slide) { + //Slide over content + if (slide) { + sidebar.addClass('control-sidebar-open'); + } else { + //Push the content by adding the open class to the body instead + //of the sidebar itself + $('body').addClass('control-sidebar-open'); + } + }, + //Close the control sidebar + close: function (sidebar, slide) { + if (slide) { + sidebar.removeClass('control-sidebar-open'); + } else { + $('body').removeClass('control-sidebar-open'); + } + }, + _fix: function (sidebar) { + var _this = this; + if ($("body").hasClass('layout-boxed')) { + sidebar.css('position', 'absolute'); + sidebar.height($(".wrapper").height()); + if (_this.hasBindedResize) { + return; + } + $(window).resize(function () { + _this._fix(sidebar); + }); + _this.hasBindedResize = true; + } else { + sidebar.css({ + 'position': 'fixed', + 'height': 'auto' + }); + } + }, + _fixForFixed: function (sidebar) { + sidebar.css({ + 'position': 'fixed', + 'max-height': '100%', + 'overflow': 'auto', + 'padding-bottom': '50px' + }); + }, + _fixForContent: function (sidebar) { + $(".content-wrapper, .right-side").css('min-height', sidebar.height()); + } + }; + + /* BoxWidget + * ========= + * BoxWidget is a plugin to handle collapsing and + * removing boxes from the screen. + * + * @type Object + * @usage $.AdminLTE.boxWidget.activate() + * Set all your options in the main $.AdminLTE.options object + */ + $.AdminLTE.boxWidget = { + selectors: $.AdminLTE.options.boxWidgetOptions.boxWidgetSelectors, + icons: $.AdminLTE.options.boxWidgetOptions.boxWidgetIcons, + animationSpeed: $.AdminLTE.options.animationSpeed, + activate: function (_box) { + var _this = this; + if (!_box) { + _box = document; // activate all boxes per default + } + //Listen for collapse event triggers + $(_box).on('click', _this.selectors.collapse, function (e) { + e.preventDefault(); + _this.collapse($(this)); + }); + + //Listen for remove event triggers + $(_box).on('click', _this.selectors.remove, function (e) { + e.preventDefault(); + _this.remove($(this)); + }); + }, + collapse: function (element) { + var _this = this; + //Find the box parent + var box = element.parents(".box").first(); + //Find the body and the footer + var box_content = box.find("> .box-body, > .box-footer, > form >.box-body, > form > .box-footer"); + if (!box.hasClass("collapsed-box")) { + //Convert minus into plus + element.children(":first") + .removeClass(_this.icons.collapse) + .addClass(_this.icons.open); + //Hide the content + box_content.slideUp(_this.animationSpeed, function () { + box.addClass("collapsed-box"); + }); + } else { + //Convert plus into minus + element.children(":first") + .removeClass(_this.icons.open) + .addClass(_this.icons.collapse); + //Show the content + box_content.slideDown(_this.animationSpeed, function () { + box.removeClass("collapsed-box"); + }); + } + }, + remove: function (element) { + //Find the box parent + var box = element.parents(".box").first(); + box.slideUp(this.animationSpeed); + } + }; +} + +/* ------------------ + * - Custom Plugins - + * ------------------ + * All custom plugins are defined below. + */ + +/* + * BOX REFRESH BUTTON + * ------------------ + * This is a custom plugin to use with the component BOX. It allows you to add + * a refresh button to the box. It converts the box's state to a loading state. + * + * @type plugin + * @usage $("#box-widget").boxRefresh( options ); + */ +(function ($) { + + "use strict"; + + $.fn.boxRefresh = function (options) { + + // Render options + var settings = $.extend({ + //Refresh button selector + trigger: ".refresh-btn", + //File source to be loaded (e.g: ajax/src.php) + source: "", + //Callbacks + onLoadStart: function (box) { + return box; + }, //Right after the button has been clicked + onLoadDone: function (box) { + return box; + } //When the source has been loaded + + }, options); + + //The overlay + var overlay = $('

'); + + return this.each(function () { + //if a source is specified + if (settings.source === "") { + if (window.console) { + window.console.log("Please specify a source first - boxRefresh()"); + } + return; + } + //the box + var box = $(this); + //the button + var rBtn = box.find(settings.trigger).first(); + + //On trigger click + rBtn.on('click', function (e) { + e.preventDefault(); + //Add loading overlay + start(box); + + //Perform ajax call + box.find(".box-body").load(settings.source, function () { + done(box); + }); + }); + }); + + function start(box) { + //Add overlay and loading img + box.append(overlay); + + settings.onLoadStart.call(box); + } + + function done(box) { + //Remove overlay and loading img + box.find(overlay).remove(); + + settings.onLoadDone.call(box); + } + + }; + +})(jQuery); + +/* + * EXPLICIT BOX CONTROLS + * ----------------------- + * This is a custom plugin to use with the component BOX. It allows you to activate + * a box inserted in the DOM after the app.js was loaded, toggle and remove box. + * + * @type plugin + * @usage $("#box-widget").activateBox(); + * @usage $("#box-widget").toggleBox(); + * @usage $("#box-widget").removeBox(); + */ +(function ($) { + + 'use strict'; + + $.fn.activateBox = function () { + $.AdminLTE.boxWidget.activate(this); + }; + + $.fn.toggleBox = function () { + var button = $($.AdminLTE.boxWidget.selectors.collapse, this); + $.AdminLTE.boxWidget.collapse(button); + }; + + $.fn.removeBox = function () { + var button = $($.AdminLTE.boxWidget.selectors.remove, this); + $.AdminLTE.boxWidget.remove(button); + }; + +})(jQuery); + +/* + * TODO LIST CUSTOM PLUGIN + * ----------------------- + * This plugin depends on iCheck plugin for checkbox and radio inputs + * + * @type plugin + * @usage $("#todo-widget").todolist( options ); + */ +(function ($) { + + 'use strict'; + + $.fn.todolist = function (options) { + // Render options + var settings = $.extend({ + //When the user checks the input + onCheck: function (ele) { + return ele; + }, + //When the user unchecks the input + onUncheck: function (ele) { + return ele; + } + }, options); + + return this.each(function () { + + if (typeof $.fn.iCheck != 'undefined') { + $('input', this).on('ifChecked', function () { + var ele = $(this).parents("li").first(); + ele.toggleClass("done"); + settings.onCheck.call(ele); + }); + + $('input', this).on('ifUnchecked', function () { + var ele = $(this).parents("li").first(); + ele.toggleClass("done"); + settings.onUncheck.call(ele); + }); + } else { + $('input', this).on('change', function () { + var ele = $(this).parents("li").first(); + ele.toggleClass("done"); + if ($('input', ele).is(":checked")) { + settings.onCheck.call(ele); + } else { + settings.onUncheck.call(ele); + } + }); + } + }); + }; +}(jQuery)); diff --git a/renren-generator/src/main/resources/static/libs/app.min.js b/renren-generator/src/main/resources/static/libs/app.min.js new file mode 100644 index 0000000..51d5010 --- /dev/null +++ b/renren-generator/src/main/resources/static/libs/app.min.js @@ -0,0 +1,13 @@ +/*! AdminLTE app.js + * ================ + * Main JS application file for AdminLTE v2. This file + * should be included in all pages. It controls some layout + * options and implements exclusive AdminLTE plugins. + * + * @Author Almsaeed Studio + * @Support + * @Email + * @version 2.3.7 + * @license MIT + */ +function _init(){"use strict";$.AdminLTE.layout={activate:function(){var a=this;a.fix(),a.fixSidebar(),$(window,".wrapper").resize(function(){a.fix(),a.fixSidebar()})},fix:function(){var a=$(".main-header").outerHeight()+$(".main-footer").outerHeight(),b=$(window).height(),c=$(".sidebar").height();if($("body").hasClass("fixed"))$(".content-wrapper, .right-side").css("min-height",b-$(".main-footer").outerHeight());else{var d;b>=c?($(".content-wrapper, .right-side").css("min-height",b-a),d=b-a):($(".content-wrapper, .right-side").css("min-height",c),d=c);var e=$($.AdminLTE.options.controlSidebarOptions.selector);"undefined"!=typeof e&&e.height()>d&&$(".content-wrapper, .right-side").css("min-height",e.height())}},fixSidebar:function(){return $("body").hasClass("fixed")?("undefined"==typeof $.fn.slimScroll&&window.console&&window.console.error("Error: the fixed layout requires the slimscroll plugin!"),void($.AdminLTE.options.sidebarSlimScroll&&"undefined"!=typeof $.fn.slimScroll&&($(".sidebar").slimScroll({destroy:!0}).height("auto"),$(".sidebar").slimscroll({height:$(window).height()-$(".main-header").height()+"px",color:"rgba(0,0,0,0.2)",size:"3px"})))):void("undefined"!=typeof $.fn.slimScroll&&$(".sidebar").slimScroll({destroy:!0}).height("auto"))}},$.AdminLTE.pushMenu={activate:function(a){var b=$.AdminLTE.options.screenSizes;$(document).on("click",a,function(a){a.preventDefault(),$(window).width()>b.sm-1?$("body").hasClass("sidebar-collapse")?$("body").removeClass("sidebar-collapse").trigger("expanded.pushMenu"):$("body").addClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").hasClass("sidebar-open")?$("body").removeClass("sidebar-open").removeClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").addClass("sidebar-open").trigger("expanded.pushMenu")}),$(".content-wrapper").click(function(){$(window).width()<=b.sm-1&&$("body").hasClass("sidebar-open")&&$("body").removeClass("sidebar-open")}),($.AdminLTE.options.sidebarExpandOnHover||$("body").hasClass("fixed")&&$("body").hasClass("sidebar-mini"))&&this.expandOnHover()},expandOnHover:function(){var a=this,b=$.AdminLTE.options.screenSizes.sm-1;$(".main-sidebar").hover(function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-collapse")&&$(window).width()>b&&a.expand()},function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-expanded-on-hover")&&$(window).width()>b&&a.collapse()})},expand:function(){$("body").removeClass("sidebar-collapse").addClass("sidebar-expanded-on-hover")},collapse:function(){$("body").hasClass("sidebar-expanded-on-hover")&&$("body").removeClass("sidebar-expanded-on-hover").addClass("sidebar-collapse")}},$.AdminLTE.tree=function(a){var b=this,c=$.AdminLTE.options.animationSpeed;$(document).off("click",a+" li a").on("click",a+" li a",function(a){var d=$(this),e=d.next();if(e.is(".treeview-menu")&&e.is(":visible")&&!$("body").hasClass("sidebar-collapse"))e.slideUp(c,function(){e.removeClass("menu-open")}),e.parent("li").removeClass("active");else if(e.is(".treeview-menu")&&!e.is(":visible")){var f=d.parents("ul").first(),g=f.find("ul:visible").slideUp(c);g.removeClass("menu-open");var h=d.parent("li");e.slideDown(c,function(){e.addClass("menu-open"),f.find("li.active").removeClass("active"),h.addClass("active"),b.layout.fix()})}e.is(".treeview-menu")&&a.preventDefault()})},$.AdminLTE.controlSidebar={activate:function(){var a=this,b=$.AdminLTE.options.controlSidebarOptions,c=$(b.selector),d=$(b.toggleBtnSelector);d.on("click",function(d){d.preventDefault(),c.hasClass("control-sidebar-open")||$("body").hasClass("control-sidebar-open")?a.close(c,b.slide):a.open(c,b.slide)});var e=$(".control-sidebar-bg");a._fix(e),$("body").hasClass("fixed")?a._fixForFixed(c):$(".content-wrapper, .right-side").height() .box-body, > .box-footer, > form >.box-body, > form > .box-footer");c.hasClass("collapsed-box")?(a.children(":first").removeClass(b.icons.open).addClass(b.icons.collapse),d.slideDown(b.animationSpeed,function(){c.removeClass("collapsed-box")})):(a.children(":first").removeClass(b.icons.collapse).addClass(b.icons.open),d.slideUp(b.animationSpeed,function(){c.addClass("collapsed-box")}))},remove:function(a){var b=a.parents(".box").first();b.slideUp(this.animationSpeed)}}}if("undefined"==typeof jQuery)throw new Error("AdminLTE requires jQuery");$.AdminLTE={},$.AdminLTE.options={navbarMenuSlimscroll:!0,navbarMenuSlimscrollWidth:"3px",navbarMenuHeight:"200px",animationSpeed:500,sidebarToggleSelector:"[data-toggle='offcanvas']",sidebarPushMenu:!0,sidebarSlimScroll:!0,sidebarExpandOnHover:!1,enableBoxRefresh:!0,enableBSToppltip:!0,BSTooltipSelector:"[data-toggle='tooltip']",enableFastclick:!1,enableControlSidebar:!0,controlSidebarOptions:{toggleBtnSelector:"[data-toggle='control-sidebar']",selector:".control-sidebar",slide:!0},enableBoxWidget:!0,boxWidgetOptions:{boxWidgetIcons:{collapse:"fa-minus",open:"fa-plus",remove:"fa-times"},boxWidgetSelectors:{remove:'[data-widget="remove"]',collapse:'[data-widget="collapse"]'}},directChat:{enable:!0,contactToggleSelector:'[data-widget="chat-pane-toggle"]'},colors:{lightBlue:"#3c8dbc",red:"#f56954",green:"#00a65a",aqua:"#00c0ef",yellow:"#f39c12",blue:"#0073b7",navy:"#001F3F",teal:"#39CCCC",olive:"#3D9970",lime:"#01FF70",orange:"#FF851B",fuchsia:"#F012BE",purple:"#8E24AA",maroon:"#D81B60",black:"#222222",gray:"#d2d6de"},screenSizes:{xs:480,sm:768,md:992,lg:1200}},$(function(){"use strict";$("body").removeClass("hold-transition"),"undefined"!=typeof AdminLTEOptions&&$.extend(!0,$.AdminLTE.options,AdminLTEOptions);var a=$.AdminLTE.options;_init(),$.AdminLTE.layout.activate(),$.AdminLTE.tree(".sidebar"),a.enableControlSidebar&&$.AdminLTE.controlSidebar.activate(),a.navbarMenuSlimscroll&&"undefined"!=typeof $.fn.slimscroll&&$(".navbar .menu").slimscroll({height:a.navbarMenuHeight,alwaysVisible:!1,size:a.navbarMenuSlimscrollWidth}).css("width","100%"),a.sidebarPushMenu&&$.AdminLTE.pushMenu.activate(a.sidebarToggleSelector),a.enableBSToppltip&&$("body").tooltip({selector:a.BSTooltipSelector}),a.enableBoxWidget&&$.AdminLTE.boxWidget.activate(),a.enableFastclick&&"undefined"!=typeof FastClick&&FastClick.attach(document.body),a.directChat.enable&&$(document).on("click",a.directChat.contactToggleSelector,function(){var a=$(this).parents(".direct-chat").first();a.toggleClass("direct-chat-contacts-open")}),$('.btn-group[data-toggle="btn-toggle"]').each(function(){var a=$(this);$(this).find(".btn").on("click",function(b){a.find(".btn.active").removeClass("active"),$(this).addClass("active"),b.preventDefault()})})}),function(a){"use strict";a.fn.boxRefresh=function(b){function c(a){a.append(f),e.onLoadStart.call(a)}function d(a){a.find(f).remove(),e.onLoadDone.call(a)}var e=a.extend({trigger:".refresh-btn",source:"",onLoadStart:function(a){return a},onLoadDone:function(a){return a}},b),f=a('
');return this.each(function(){if(""===e.source)return void(window.console&&window.console.log("Please specify a source first - boxRefresh()"));var b=a(this),f=b.find(e.trigger).first();f.on("click",function(a){a.preventDefault(),c(b),b.find(".box-body").load(e.source,function(){d(b)})})})}}(jQuery),function(a){"use strict";a.fn.activateBox=function(){a.AdminLTE.boxWidget.activate(this)},a.fn.toggleBox=function(){var b=a(a.AdminLTE.boxWidget.selectors.collapse,this);a.AdminLTE.boxWidget.collapse(b)},a.fn.removeBox=function(){var b=a(a.AdminLTE.boxWidget.selectors.remove,this);a.AdminLTE.boxWidget.remove(b)}}(jQuery),function(a){"use strict";a.fn.todolist=function(b){var c=a.extend({onCheck:function(a){return a},onUncheck:function(a){return a}},b);return this.each(function(){"undefined"!=typeof a.fn.iCheck?(a("input",this).on("ifChecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onCheck.call(b)}),a("input",this).on("ifUnchecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onUncheck.call(b)})):a("input",this).on("change",function(){var b=a(this).parents("li").first();b.toggleClass("done"),a("input",b).is(":checked")?c.onCheck.call(b):c.onUncheck.call(b)})})}}(jQuery); \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/libs/bootstrap.min.js b/renren-generator/src/main/resources/static/libs/bootstrap.min.js new file mode 100644 index 0000000..9bcd2fc --- /dev/null +++ b/renren-generator/src/main/resources/static/libs/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/libs/fastclick.min.js b/renren-generator/src/main/resources/static/libs/fastclick.min.js new file mode 100644 index 0000000..131e29e --- /dev/null +++ b/renren-generator/src/main/resources/static/libs/fastclick.min.js @@ -0,0 +1 @@ +!function e(t,n,r){function i(s,a){if(!n[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(o)return o(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[s]={exports:{}};t[s][0].call(u.exports,function(e){var n=t[s][1][e];return i(n?n:e)},u,u.exports,e,t,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;sc;c++)a[s[c]]=i(a[s[c]],a);r&&(t.addEventListener("mouseover",this.onMouse,!0),t.addEventListener("mousedown",this.onMouse,!0),t.addEventListener("mouseup",this.onMouse,!0)),t.addEventListener("click",this.onClick,!0),t.addEventListener("touchstart",this.onTouchStart,!1),t.addEventListener("touchmove",this.onTouchMove,!1),t.addEventListener("touchend",this.onTouchEnd,!1),t.addEventListener("touchcancel",this.onTouchCancel,!1),Event.prototype.stopImmediatePropagation||(t.removeEventListener=function(e,n,r){var i=Node.prototype.removeEventListener;"click"===e?i.call(t,e,n.hijacked||n,r):i.call(t,e,n,r)},t.addEventListener=function(e,n,r){var i=Node.prototype.addEventListener;"click"===e?i.call(t,e,n.hijacked||(n.hijacked=function(e){e.propagationStopped||n(e)}),r):i.call(t,e,n,r)}),"function"==typeof t.onclick&&(o=t.onclick,t.addEventListener("click",function(e){o(e)},!1),t.onclick=null)}}var n=navigator.userAgent.indexOf("Windows Phone")>=0,r=navigator.userAgent.indexOf("Android")>0&&!n,i=/iP(ad|hone|od)/.test(navigator.userAgent)&&!n,o=i&&/OS 4_\d(_\d)?/.test(navigator.userAgent),s=i&&/OS [6-7]_\d/.test(navigator.userAgent),a=navigator.userAgent.indexOf("BB10")>0;e.prototype.needsClick=function(e){switch(e.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(e.disabled)return!0;break;case"input":if(i&&"file"===e.type||e.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(e.className)},e.prototype.needsFocus=function(e){switch(e.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!r;case"input":switch(e.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!e.disabled&&!e.readOnly;default:return/\bneedsfocus\b/.test(e.className)}},e.prototype.sendClick=function(e,t){var n,r;document.activeElement&&document.activeElement!==e&&document.activeElement.blur(),r=t.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(e),!0,!0,window,1,r.screenX,r.screenY,r.clientX,r.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,e.dispatchEvent(n)},e.prototype.determineEventType=function(e){return r&&"select"===e.tagName.toLowerCase()?"mousedown":"click"},e.prototype.focus=function(e){var t;i&&e.setSelectionRange&&0!==e.type.indexOf("date")&&"time"!==e.type&&"month"!==e.type?(t=e.value.length,e.setSelectionRange(t,t)):e.focus()},e.prototype.updateScrollParent=function(e){var t,n;if(t=e.fastClickScrollParent,!t||!t.contains(e)){n=e;do{if(n.scrollHeight>n.offsetHeight){t=n,e.fastClickScrollParent=n;break}n=n.parentElement}while(n)}t&&(t.fastClickLastScrollTop=t.scrollTop)},e.prototype.getTargetElementFromEventTarget=function(e){return e.nodeType===Node.TEXT_NODE?e.parentNode:e},e.prototype.onTouchStart=function(e){var t,n,r;if(e.targetTouches.length>1)return!0;if(t=this.getTargetElementFromEventTarget(e.target),n=e.targetTouches[0],i){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!o){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return e.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(t)}}return this.trackingClick=!0,this.trackingClickStart=e.timeStamp,this.targetElement=t,this.touchStartX=n.pageX,this.touchStartY=n.pageY,e.timeStamp-this.lastClickTimen||Math.abs(t.pageY-this.touchStartY)>n?!0:!1},e.prototype.onTouchMove=function(e){return this.trackingClick?((this.targetElement!==this.getTargetElementFromEventTarget(e.target)||this.touchHasMoved(e))&&(this.trackingClick=!1,this.targetElement=null),!0):!0},e.prototype.findControl=function(e){return void 0!==e.control?e.control:e.htmlFor?document.getElementById(e.htmlFor):e.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},e.prototype.onTouchEnd=function(e){var t,n,a,c,l,u=this.targetElement;if(!this.trackingClick)return!0;if(e.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=e.timeStamp,n=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,s&&(l=e.changedTouches[0],u=document.elementFromPoint(l.pageX-window.pageXOffset,l.pageY-window.pageYOffset)||u,u.fastClickScrollParent=this.targetElement.fastClickScrollParent),a=u.tagName.toLowerCase(),"label"===a){if(t=this.findControl(u)){if(this.focus(u),r)return!1;u=t}}else if(this.needsFocus(u))return e.timeStamp-n>100||i&&window.top!==window&&"input"===a?(this.targetElement=null,!1):(this.focus(u),this.sendClick(u,e),i&&"select"===a||(this.targetElement=null,e.preventDefault()),!1);return i&&!o&&(c=u.fastClickScrollParent,c&&c.fastClickLastScrollTop!==c.scrollTop)?!0:(this.needsClick(u)||(e.preventDefault(),this.sendClick(u,e)),!1)},e.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},e.prototype.onMouse=function(e){return this.targetElement?e.forwardedTouchEvent?!0:e.cancelable&&(!this.needsClick(this.targetElement)||this.cancelNextClick)?(e.stopImmediatePropagation?e.stopImmediatePropagation():e.propagationStopped=!0,e.stopPropagation(),e.preventDefault(),!1):!0:!0},e.prototype.onClick=function(e){var t;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===e.target.type&&0===e.detail?!0:(t=this.onMouse(e),t||(this.targetElement=null),t)},e.prototype.destroy=function(){var e=this.layer;r&&(e.removeEventListener("mouseover",this.onMouse,!0),e.removeEventListener("mousedown",this.onMouse,!0),e.removeEventListener("mouseup",this.onMouse,!0)),e.removeEventListener("click",this.onClick,!0),e.removeEventListener("touchstart",this.onTouchStart,!1),e.removeEventListener("touchmove",this.onTouchMove,!1),e.removeEventListener("touchend",this.onTouchEnd,!1),e.removeEventListener("touchcancel",this.onTouchCancel,!1)},e.notNeeded=function(e){var t,n,i,o;if("undefined"==typeof window.ontouchstart)return!0;if(n=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!r)return!0;if(t=document.querySelector("meta[name=viewport]")){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(n>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(a&&(i=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),i[1]>=10&&i[2]>=3&&(t=document.querySelector("meta[name=viewport]")))){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===e.style.msTouchAction||"manipulation"===e.style.touchAction?!0:(o=+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1],o>=27&&(t=document.querySelector("meta[name=viewport]"),t&&(-1!==t.content.indexOf("user-scalable=no")||document.documentElement.scrollWidth<=window.outerWidth))?!0:"none"===e.style.touchAction||"manipulation"===e.style.touchAction?!0:!1)},e.attach=function(t,n){return new e(t,n)},"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return e}):"undefined"!=typeof t&&t.exports?(t.exports=e.attach,t.exports.FastClick=e):window.FastClick=e}()},{}],2:[function(e){window.Origami={fastclick:e("./bower_components/fastclick/lib/fastclick.js")}},{"./bower_components/fastclick/lib/fastclick.js":1}]},{},[2]);;(function() {function trigger(){document.dispatchEvent(new CustomEvent('o.load'))};document.addEventListener('load',trigger);if (document.readyState==='ready') trigger();}());(function() {function trigger(){document.dispatchEvent(new CustomEvent('o.DOMContentLoaded'))};document.addEventListener('DOMContentLoaded',trigger);if (document.readyState==='interactive') trigger();}()) \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/libs/jquery.min.js b/renren-generator/src/main/resources/static/libs/jquery.min.js new file mode 100644 index 0000000..4024b66 --- /dev/null +++ b/renren-generator/src/main/resources/static/libs/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="
",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; +}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}e.vessel(f,function(n,r,d){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){l.parents("."+s[0])[0]||(l.data("display",l.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+s[0]+a).find("."+s[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=d),e.layero=i("#"+s[0]+a),t.scrollbar||s.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",l[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),s.anim[t.anim]&&e.layero.addClass(s.anim[t.anim]).data("anim",!0)}},l.pt.auto=function(e){function t(e){e=l.find(e),e.height(f[1]-c-d-2*(0|parseFloat(e.css("padding"))))}var a=this,o=a.config,l=i("#"+s[0]+e);""===o.area[0]&&o.maxWidth>0&&(r.ie&&r.ie<8&&o.btn&&l.width(l.innerWidth()),l.outerWidth()>o.maxWidth&&l.width(o.maxWidth));var f=[l.innerWidth(),l.innerHeight()],c=l.find(s[1]).outerHeight()||0,d=l.find("."+s[6]).outerHeight()||0;switch(o.type){case 2:t("iframe");break;default:""===o.area[1]?o.fixed&&f[1]>=n.height()&&(f[1]=n.height(),t("."+s[5])):t("."+s[5])}return a},l.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(s[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},l.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var l={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),l.autoLeft=function(){l.left+o[0]-n.width()>0?(l.tipLeft=l.left+l.width-o[0],f.css({right:12,left:"auto"})):l.tipLeft=l.left},l.where=[function(){l.autoLeft(),l.tipTop=l.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){l.tipLeft=l.left+l.width+10,l.tipTop=l.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){l.autoLeft(),l.tipTop=l.top+l.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){l.tipLeft=l.left-o[0]-10,l.tipTop=l.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],l.where[c-1](),1===c?l.top-(n.scrollTop()+o[1]+16)<0&&l.where[2]():2===c?n.width()-(l.left+l.width+o[0]+16)>0||l.where[3]():3===c?l.top-n.scrollTop()+l.height+o[1]+16-n.height()>0&&l.where[0]():4===c&&o[0]+16-l.left>0&&l.where[1](),a.find("."+s[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:l.tipLeft-(t.fixed?n.scrollLeft():0),top:l.tipTop-(t.fixed?n.scrollTop():0)})},l.pt.move=function(){var e=this,t=e.config,a=i(document),l=e.layero,s=l.find(t.move),f=l.find(".layui-layer-resize"),c={};return t.move&&s.css("cursor","move"),s.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(l.css("left")),e.clientY-parseFloat(l.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[l.outerWidth(),l.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],s="fixed"===l.css("position");if(i.preventDefault(),c.stX=s?0:n.scrollLeft(),c.stY=s?0:n.scrollTop(),!t.moveOut){var f=n.width()-l.outerWidth()+c.stX,d=n.height()-l.outerHeight()+c.stY;af&&(a=f),od&&(o=d)}l.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd()),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},l.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+s[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+s[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+s[0])[0]||1==n.attr("layer")&&i("."+s[0]).length<1&&n.removeAttr("layer").show(),n=null})},l.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+s[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},l.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){s.html.attr("layer-full")==e&&(s.html[0].style.removeProperty?s.html[0].style.removeProperty("overflow"):s.html[0].style.removeAttribute("overflow"),s.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+s[4]).attr("times"),i("#"+s[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+s[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+s[0]+e),a=n.find(s[1]).outerHeight()||0,o=n.find("."+s[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+s[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+s[0]+e),r=a.find(".layui-layer-content"),l=a.attr("type"),f=a.find(s[1]).outerHeight()||0,c=a.find("."+s[6]).outerHeight()||0;a.attr("minLeft");l!==o.type[3]&&l!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+s[6]).outerHeight(),l===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+s[0]+e),l=a.find(s[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:l,left:f,top:n.height()-l,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(s[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+s[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(s[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+s[0]+e);o.record(a),s.html.attr("layer-full")||s.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+s[0]+(t||r.index)).find(s[1]);n.html(e)},r.close=function(e){var t=i("#"+s[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var l="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+s[5]+")").remove();for(var a=t.find("."+l),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(l)}else{if(n===o.type[2])try{var f=i("#"+s[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+s[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}};t.data("anim")&&t.addClass(a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),"function"==typeof o.end[e]&&o.end[e](),delete o.end[e],t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),setTimeout(function(){f()},r.ie&&r.ie<10||!t.data("anim")?0:200)}},r.closeAll=function(e){i.each(i("."+s[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var l,s=2==e.formType?'":function(){return''}();return r.open(i.extend({type:1,btn:["确定","取消"],content:s,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){l=e.find(".layui-layer-input"),l.focus()},resize:!1,yes:function(i){var n=l.val();""===n?l.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",l,{tips:1}):t&&t(n,i,l)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{};return r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,n="";if(e>0)for(n=''+t[0].title+"";i"+t[i].title+"";return n}(),content:'
    '+function(){var e=t.length,i=1,n="";if(e>0)for(n='
  • '+(t[0].content||"no content")+"
  • ";i'+(t[i].content||"no content")+"";return n}()+"
",success:function(t){var n=t.find(".layui-layer-title").children(),a=t.find(".layui-layer-tabmain").children();n.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var n=i(this),o=n.index();n.addClass("layui-layer-tabnow").siblings().removeClass("layui-layer-tabnow"),a.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)})}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var l={};if(t=t||{},t.photos){var s=t.photos.constructor===Object,f=s?t.photos:{},d=f.data||[],u=f.start||0;if(l.imgIndex=(0|u)+1,t.img=t.img||"img",s){if(0===d.length)return r.msg("没有图片")}else{var y=i(t.photos),p=function(){d=[],y.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),d.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(p(),0===d.length)return;if(n||y.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:d,tab:t.tab},full:t.full}),!0),p()}),!n)return}l.imgprev=function(e){l.imgIndex--,l.imgIndex<1&&(l.imgIndex=d.length),l.tabimg(e)},l.imgnext=function(e,t){l.imgIndex++,l.imgIndex>d.length&&(l.imgIndex=1,t)||l.tabimg(e)},l.keyup=function(e){if(!l.end){var t=e.keyCode;e.preventDefault(),37===t?l.imgprev(!0):39===t?l.imgnext(!0):27===t&&r.close(l.index)}},l.tabimg=function(e){d.length<=1||(f.start=l.imgIndex-1,r.close(l.index),r.photos(t,!0,e))},l.event=function(){l.bigimg.hover(function(){l.imgsee.show()},function(){l.imgsee.hide()}),l.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),l.imgprev()}),l.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),l.imgnext()}),i(document).on("keyup",l.keyup)},l.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(d[u].src,function(n){r.close(l.loadi),l.index=r.open(i.extend({type:1,area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(d[u].alt||
'+(d.length>1?'':"")+'
'+(d[u].alt||"")+""+l.imgIndex+"/"+d.length+"
",success:function(e,i){l.bigimg=e.find(".layui-layer-phimg"),l.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),l.event(e),t.tab&&t.tab(d[u],e)},end:function(){l.end=!0,i(document).off("keyup",l.keyup)}},t))},function(){r.close(l.loadi),r.msg("当前图片地址异常
是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){d.length>1&&l.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),s.html=i("html"),r.open=function(e){var t=new l(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.jquery),e.layer=r,t("layer",r)})):"function"==typeof define?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/plugins/layer/mobile/layer.js b/renren-generator/src/main/resources/static/plugins/layer/mobile/layer.js new file mode 100644 index 0000000..f9cf693 --- /dev/null +++ b/renren-generator/src/main/resources/static/plugins/layer/mobile/layer.js @@ -0,0 +1,2 @@ +/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */ + ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

'+(e?n.title[0]:n.title)+"

":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
'+e+"
"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

'+(n.content||"")+"

"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
':"")+'
"+l+'
'+n.content+"
"+c+"
",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;odiv{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/renren-generator/src/main/resources/static/plugins/layer/skin/default/icon-ext.png b/renren-generator/src/main/resources/static/plugins/layer/skin/default/icon-ext.png new file mode 100644 index 0000000000000000000000000000000000000000..bbbb669bb311514baa5db3a6a00b4644d0e280f1 GIT binary patch literal 5911 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 bWW^%>x7XlHV^#Q1uOX^B?ki3(VEg|7!QHuF literal 0 HcmV?d00001 diff --git a/renren-generator/src/main/resources/static/plugins/layer/skin/default/loading-1.gif b/renren-generator/src/main/resources/static/plugins/layer/skin/default/loading-1.gif new file mode 100644 index 0000000000000000000000000000000000000000..db3a483e4b74971fbfb1cc0fb6499852cedfe650 GIT binary patch literal 701 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 page(@ApiIgnore @RequestParam Map params){ + PageData<${className}DTO> page = ${classname}Service.page(params); + + return new Result>().ok(page); + } + + @GetMapping("{id}") + @ApiOperation("信息") + @RequiresPermissions("${moduleName}:${pathName}:info") + public Result<${className}DTO> get(@PathVariable("id") Long id){ + ${className}DTO data = ${classname}Service.get(id); + + return new Result<${className}DTO>().ok(data); + } + + @PostMapping + @ApiOperation("保存") + @LogOperation("保存") + @RequiresPermissions("${moduleName}:${pathName}:save") + public Result save(@RequestBody ${className}DTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class); + + ${classname}Service.save(dto); + + return new Result(); + } + + @PutMapping + @ApiOperation("修改") + @LogOperation("修改") + @RequiresPermissions("${moduleName}:${pathName}:update") + public Result update(@RequestBody ${className}DTO dto){ + //效验数据 + ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class); + + ${classname}Service.update(dto); + + return new Result(); + } + + @DeleteMapping + @ApiOperation("删除") + @LogOperation("删除") + @RequiresPermissions("${moduleName}:${pathName}:delete") + public Result delete(@RequestBody Long[] ids){ + //效验数据 + AssertUtils.isArrayEmpty(ids, "id"); + + ${classname}Service.delete(ids); + + return new Result(); + } + + @GetMapping("export") + @ApiOperation("导出") + @LogOperation("导出") + @RequiresPermissions("${moduleName}:${pathName}:export") + public void export(@ApiIgnore @RequestParam Map params, HttpServletResponse response) throws Exception { + List<${className}DTO> list = ${classname}Service.list(params); + + ExcelUtils.exportExcelToTarget(response, null, list, ${className}Excel.class); + } + +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/DTO.java.vm b/renren-generator/src/main/resources/template/DTO.java.vm new file mode 100644 index 0000000..5080f4e --- /dev/null +++ b/renren-generator/src/main/resources/template/DTO.java.vm @@ -0,0 +1,31 @@ +package ${package}.modules.${moduleName}.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +#if(${hasBigDecimal}) +import java.math.BigDecimal; +#end + +/** + * ${comments} + * + * @author ${author} ${email} + * @since ${version} ${date} + */ +@Data +@ApiModel(value = "${comments}") +public class ${className}DTO implements Serializable { + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) + @ApiModelProperty(value = "$column.comments") + private $column.attrType $column.attrname; + +#end + +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/Dao.java.vm b/renren-generator/src/main/resources/template/Dao.java.vm new file mode 100644 index 0000000..3e3554a --- /dev/null +++ b/renren-generator/src/main/resources/template/Dao.java.vm @@ -0,0 +1,16 @@ +package ${package}.modules.${moduleName}.dao; + +import ${package}.common.dao.BaseDao; +import ${package}.modules.${moduleName}.entity.${className}Entity; +import org.apache.ibatis.annotations.Mapper; + +/** + * ${comments} + * + * @author ${author} ${email} + * @since ${version} ${date} + */ +@Mapper +public interface ${className}Dao extends BaseDao<${className}Entity> { + +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/Dao.xml.vm b/renren-generator/src/main/resources/template/Dao.xml.vm new file mode 100644 index 0000000..77acb47 --- /dev/null +++ b/renren-generator/src/main/resources/template/Dao.xml.vm @@ -0,0 +1,13 @@ + + + + + + +#foreach($column in $columns) + +#end + + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/Entity.java.vm b/renren-generator/src/main/resources/template/Entity.java.vm new file mode 100644 index 0000000..ad363f6 --- /dev/null +++ b/renren-generator/src/main/resources/template/Entity.java.vm @@ -0,0 +1,27 @@ +package ${package}.modules.${moduleName}.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +#if(${hasBigDecimal}) +import java.math.BigDecimal; +#end +import java.util.Date; + +/** + * ${comments} + * + * @author ${author} ${email} + * @since ${version} ${date} + */ +@Data +@TableName("${tableName}") +public class ${className}Entity { + +#foreach ($column in $columns) + /** + * $column.comments + */ + private $column.attrType $column.attrname; +#end +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/Excel.java.vm b/renren-generator/src/main/resources/template/Excel.java.vm new file mode 100644 index 0000000..330a021 --- /dev/null +++ b/renren-generator/src/main/resources/template/Excel.java.vm @@ -0,0 +1,24 @@ +package ${package}.modules.${moduleName}.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import lombok.Data; + +#if(${hasBigDecimal}) +import java.math.BigDecimal; +#end +import java.util.Date; + +/** + * ${comments} + * + * @author ${author} ${email} + * @since ${version} ${date} + */ +@Data +public class ${className}Excel { +#foreach ($column in $columns) + @Excel(name = "$!column.comments") + private $column.attrType $column.attrname; +#end + +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/Service.java.vm b/renren-generator/src/main/resources/template/Service.java.vm new file mode 100644 index 0000000..b3ee606 --- /dev/null +++ b/renren-generator/src/main/resources/template/Service.java.vm @@ -0,0 +1,15 @@ +package ${package}.modules.${moduleName}.service; + +import ${package}.common.service.CrudService; +import ${package}.modules.${moduleName}.dto.${className}DTO; +import ${package}.modules.${moduleName}.entity.${className}Entity; + +/** + * ${comments} + * + * @author ${author} ${email} + * @since ${version} ${date} + */ +public interface ${className}Service extends CrudService<${className}Entity, ${className}DTO> { + +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/ServiceImpl.java.vm b/renren-generator/src/main/resources/template/ServiceImpl.java.vm new file mode 100644 index 0000000..60361c9 --- /dev/null +++ b/renren-generator/src/main/resources/template/ServiceImpl.java.vm @@ -0,0 +1,34 @@ +package ${package}.modules.${moduleName}.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import ${package}.common.service.impl.CrudServiceImpl; +import ${package}.modules.${moduleName}.dao.${className}Dao; +import ${package}.modules.${moduleName}.dto.${className}DTO; +import ${package}.modules.${moduleName}.entity.${className}Entity; +import ${package}.modules.${moduleName}.service.${className}Service; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * ${comments} + * + * @author ${author} ${email} + * @since ${version} ${date} + */ +@Service +public class ${className}ServiceImpl extends CrudServiceImpl<${className}Dao, ${className}Entity, ${className}DTO> implements ${className}Service { + + @Override + public QueryWrapper<${className}Entity> getWrapper(Map params){ + String id = (String)params.get("id"); + + QueryWrapper<${className}Entity> wrapper = new QueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(id), "id", id); + + return wrapper; + } + + +} \ No newline at end of file diff --git a/renren-generator/src/main/resources/template/add-or-update.vue.vm b/renren-generator/src/main/resources/template/add-or-update.vue.vm new file mode 100644 index 0000000..6dbe74e --- /dev/null +++ b/renren-generator/src/main/resources/template/add-or-update.vue.vm @@ -0,0 +1,94 @@ + + + diff --git a/renren-generator/src/main/resources/template/index.vue.vm b/renren-generator/src/main/resources/template/index.vue.vm new file mode 100644 index 0000000..8db5323 --- /dev/null +++ b/renren-generator/src/main/resources/template/index.vue.vm @@ -0,0 +1,72 @@ + + + diff --git a/renren-generator/src/main/resources/template/mysql.vm b/renren-generator/src/main/resources/template/mysql.vm new file mode 100644 index 0000000..6df0745 --- /dev/null +++ b/renren-generator/src/main/resources/template/mysql.vm @@ -0,0 +1,7 @@ +-- 菜单初始SQL +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date)VALUES (${id0}, 1067246875800000035, '$!comments', '${moduleName}/${pathName}', NULL, 0, 'icon-desktop', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id1}, ${id0}, '查看', NULL, '${moduleName}:${pathName}:page,${moduleName}:${pathName}:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id2}, ${id0}, '新增', NULL, '${moduleName}:${pathName}:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id3}, ${id0}, '修改', NULL, '${moduleName}:${pathName}:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id4}, ${id0}, '删除', NULL, '${moduleName}:${pathName}:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id5}, ${id0}, '导出', NULL, '${moduleName}:${pathName}:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); diff --git a/renren-generator/src/main/resources/template/oracle.vm b/renren-generator/src/main/resources/template/oracle.vm new file mode 100644 index 0000000..f8e2e53 --- /dev/null +++ b/renren-generator/src/main/resources/template/oracle.vm @@ -0,0 +1,7 @@ +-- 菜单初始SQL +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date)VALUES (${id0}, 1067246875800000035, '$!comments', '${moduleName}/${pathName}', NULL, 0, 'icon-desktop', 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id1}, ${id0}, '查看', NULL, '${moduleName}:${pathName}:page,${moduleName}:${pathName}:info', 1, NULL, 0, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id2}, ${id0}, '新增', NULL, '${moduleName}:${pathName}:save', 1, NULL, 1, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id3}, ${id0}, '修改', NULL, '${moduleName}:${pathName}:update', 1, NULL, 2, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id4}, ${id0}, '删除', NULL, '${moduleName}:${pathName}:delete', 1, NULL, 3, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id5}, ${id0}, '导出', NULL, '${moduleName}:${pathName}:export', 1, NULL, 4, 1067246875800000001, CURRENT_DATE, 1067246875800000001, CURRENT_DATE); diff --git a/renren-generator/src/main/resources/template/postgresql.vm b/renren-generator/src/main/resources/template/postgresql.vm new file mode 100644 index 0000000..6df0745 --- /dev/null +++ b/renren-generator/src/main/resources/template/postgresql.vm @@ -0,0 +1,7 @@ +-- 菜单初始SQL +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date)VALUES (${id0}, 1067246875800000035, '$!comments', '${moduleName}/${pathName}', NULL, 0, 'icon-desktop', 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id1}, ${id0}, '查看', NULL, '${moduleName}:${pathName}:page,${moduleName}:${pathName}:info', 1, NULL, 0, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id2}, ${id0}, '新增', NULL, '${moduleName}:${pathName}:save', 1, NULL, 1, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id3}, ${id0}, '修改', NULL, '${moduleName}:${pathName}:update', 1, NULL, 2, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id4}, ${id0}, '删除', NULL, '${moduleName}:${pathName}:delete', 1, NULL, 3, 1067246875800000001, now(), 1067246875800000001, now()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id5}, ${id0}, '导出', NULL, '${moduleName}:${pathName}:export', 1, NULL, 4, 1067246875800000001, now(), 1067246875800000001, now()); diff --git a/renren-generator/src/main/resources/template/sqlserver.vm b/renren-generator/src/main/resources/template/sqlserver.vm new file mode 100644 index 0000000..55c6584 --- /dev/null +++ b/renren-generator/src/main/resources/template/sqlserver.vm @@ -0,0 +1,7 @@ +-- 菜单初始SQL +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date)VALUES (${id0}, 1067246875800000035, '$!comments', '${moduleName}/${pathName}', NULL, 0, 'icon-desktop', 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id1}, ${id0}, '查看', NULL, '${moduleName}:${pathName}:page,${moduleName}:${pathName}:info', 1, NULL, 0, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id2}, ${id0}, '新增', NULL, '${moduleName}:${pathName}:save', 1, NULL, 1, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id3}, ${id0}, '修改', NULL, '${moduleName}:${pathName}:update', 1, NULL, 2, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id4}, ${id0}, '删除', NULL, '${moduleName}:${pathName}:delete', 1, NULL, 3, 1067246875800000001, getdate(), 1067246875800000001, getdate()); +INSERT INTO sys_menu(id, pid, name, url, permissions, menu_type, icon, sort, creator, create_date, updater, update_date) VALUES (${id5}, ${id0}, '导出', NULL, '${moduleName}:${pathName}:export', 1, NULL, 4, 1067246875800000001, getdate(), 1067246875800000001, getdate()); diff --git a/renren-generator/src/main/resources/views/generator.html b/renren-generator/src/main/resources/views/generator.html new file mode 100644 index 0000000..215db65 --- /dev/null +++ b/renren-generator/src/main/resources/views/generator.html @@ -0,0 +1,35 @@ + + + +代码生成器 + + + + + + + + + + + + + + + + +
+
+
+ +
+ 查询 +  生成代码 +
+
+
+
+ + + + \ No newline at end of file diff --git a/renren-generator/src/main/resources/views/index.html b/renren-generator/src/main/resources/views/index.html new file mode 100644 index 0000000..7a28774 --- /dev/null +++ b/renren-generator/src/main/resources/views/index.html @@ -0,0 +1,115 @@ + + + + + + 人人代码生成器 + + + + + + + + + + + + + + + +
+
+ + + +
+ + + + + + + +
+ +
+ +
+ + +
+ +
+ +
+ + +
+ + Copyright © 2018 renren.io All Rights Reserved +
+ + +
+ + + +
+ + + + + + + + + + + + diff --git a/renren-generator/src/main/resources/views/main.html b/renren-generator/src/main/resources/views/main.html new file mode 100644 index 0000000..44dc010 --- /dev/null +++ b/renren-generator/src/main/resources/views/main.html @@ -0,0 +1,29 @@ + + + + + + 欢迎页 + + + + +
+
基本信息
+
+

   获取帮助

+ +

官方微信群

+
    +
  • 扫码下面的二维码,关注【人人开源】公众号,回复【加群】,即可根据提示加入微信群!
  • +
  • 微信群
  • +
+
+
+ + \ No newline at end of file