From 427dfc49c0a529fd6c9e028b84e7bb3b5c04e288 Mon Sep 17 00:00:00 2001 From: ddyd <2073699128@qq.com> Date: Tue, 8 Jul 2025 14:39:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5renrenkaiyuan=E6=90=AD?= =?UTF-8?q?=E5=BB=BA=E5=9F=BA=E6=9C=AC=E6=A1=86=E6=9E=B6=EF=BC=8C=E8=BE=85?= =?UTF-8?q?=E5=8A=A9=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- book-product/pom.xml | 6 + .../bookproduct/BookProductApplication.java | 13 - .../AttrAttrgroupRelationController.java | 90 + .../product/controller/AttrController.java | 90 + .../controller/AttrGroupController.java | 90 + .../product/controller/BrandController.java | 90 + .../CategoryBrandRelationController.java | 90 + .../controller/CategoryController.java | 90 + .../controller/CommentReplayController.java | 90 + .../ProductAttrValueController.java | 90 + .../controller/SkuImagesController.java | 90 + .../product/controller/SkuInfoController.java | 90 + .../SkuSaleAttrValueController.java | 90 + .../controller/SpuCommentController.java | 90 + .../controller/SpuImagesController.java | 90 + .../product/controller/SpuInfoController.java | 90 + .../controller/SpuInfoDescController.java | 90 + .../product/dao/AttrAttrgroupRelationDao.java | 17 + .../bookmall/product/dao/AttrDao.java | 17 + .../bookmall/product/dao/AttrGroupDao.java | 17 + .../bookmall/product/dao/BrandDao.java | 17 + .../product/dao/CategoryBrandRelationDao.java | 17 + .../bookmall/product/dao/CategoryDao.java | 17 + .../product/dao/CommentReplayDao.java | 17 + .../product/dao/ProductAttrValueDao.java | 17 + .../bookmall/product/dao/SkuImagesDao.java | 17 + .../bookmall/product/dao/SkuInfoDao.java | 17 + .../product/dao/SkuSaleAttrValueDao.java | 17 + .../bookmall/product/dao/SpuCommentDao.java | 17 + .../bookmall/product/dao/SpuImagesDao.java | 17 + .../bookmall/product/dao/SpuInfoDao.java | 17 + .../bookmall/product/dao/SpuInfoDescDao.java | 17 + .../entity/AttrAttrgroupRelationEntity.java | 40 + .../bookmall/product/entity/AttrEntity.java | 64 + .../product/entity/AttrGroupEntity.java | 48 + .../bookmall/product/entity/BrandEntity.java | 52 + .../entity/CategoryBrandRelationEntity.java | 44 + .../product/entity/CategoryEntity.java | 60 + .../product/entity/CommentReplayEntity.java | 36 + .../entity/ProductAttrValueEntity.java | 52 + .../product/entity/SkuImagesEntity.java | 44 + .../product/entity/SkuInfoEntity.java | 69 + .../entity/SkuSaleAttrValueEntity.java | 48 + .../product/entity/SpuCommentEntity.java | 88 + .../product/entity/SpuImagesEntity.java | 48 + .../product/entity/SpuInfoDescEntity.java | 32 + .../product/entity/SpuInfoEntity.java | 61 + .../service/AttrAttrgroupRelationService.java | 20 + .../product/service/AttrGroupService.java | 20 + .../bookmall/product/service/AttrService.java | 20 + .../product/service/BrandService.java | 20 + .../service/CategoryBrandRelationService.java | 20 + .../product/service/CategoryService.java | 20 + .../product/service/CommentReplayService.java | 20 + .../service/ProductAttrValueService.java | 20 + .../product/service/SkuImagesService.java | 20 + .../product/service/SkuInfoService.java | 20 + .../service/SkuSaleAttrValueService.java | 20 + .../product/service/SpuCommentService.java | 20 + .../product/service/SpuImagesService.java | 20 + .../product/service/SpuInfoDescService.java | 20 + .../product/service/SpuInfoService.java | 20 + .../AttrAttrgroupRelationServiceImpl.java | 29 + .../service/impl/AttrGroupServiceImpl.java | 29 + .../product/service/impl/AttrServiceImpl.java | 29 + .../service/impl/BrandServiceImpl.java | 29 + .../CategoryBrandRelationServiceImpl.java | 29 + .../service/impl/CategoryServiceImpl.java | 29 + .../impl/CommentReplayServiceImpl.java | 29 + .../impl/ProductAttrValueServiceImpl.java | 29 + .../service/impl/SkuImagesServiceImpl.java | 29 + .../service/impl/SkuInfoServiceImpl.java | 29 + .../impl/SkuSaleAttrValueServiceImpl.java | 29 + .../service/impl/SpuCommentServiceImpl.java | 29 + .../service/impl/SpuImagesServiceImpl.java | 29 + .../service/impl/SpuInfoDescServiceImpl.java | 29 + .../service/impl/SpuInfoServiceImpl.java | 29 + .../product/AttrAttrgroupRelationDao.xml | 15 + .../main/resources/mapper/product/AttrDao.xml | 21 + .../resources/mapper/product/AttrGroupDao.xml | 17 + .../resources/mapper/product/BrandDao.xml | 18 + .../product/CategoryBrandRelationDao.xml | 16 + .../resources/mapper/product/CategoryDao.xml | 20 + .../mapper/product/CommentReplayDao.xml | 14 + .../mapper/product/ProductAttrValueDao.xml | 18 + .../resources/mapper/product/SkuImagesDao.xml | 16 + .../resources/mapper/product/SkuInfoDao.xml | 22 + .../mapper/product/SkuSaleAttrValueDao.xml | 17 + .../mapper/product/SpuCommentDao.xml | 27 + .../resources/mapper/product/SpuImagesDao.xml | 17 + .../resources/mapper/product/SpuInfoDao.xml | 20 + .../mapper/product/SpuInfoDescDao.xml | 13 + mall-common/mall-common.iml | 15 + mall-common/pom.xml | 19 + pom.xml | 3 + renren-fast/Dockerfile | 7 + renren-fast/LICENSE | 191 + renren-fast/README.md | 113 + renren-fast/db/mysql.sql | 356 + renren-fast/db/oracle.sql | 346 + renren-fast/db/postgresql.sql | 364 + renren-fast/db/sqlserver.sql | 512 + renren-fast/docker-compose.yml | 8 + renren-fast/pom.xml | 335 + .../java/io/renren/RenrenApplication.java | 22 + .../io/renren/common/annotation/SysLog.java | 28 + .../io/renren/common/aspect/RedisAspect.java | 46 + .../io/renren/common/aspect/SysLogAspect.java | 101 + .../renren/common/exception/RRException.java | 61 + .../common/exception/RRExceptionHandler.java | 64 + .../io/renren/common/utils/BeanFindUtils.java | 65 + .../renren/common/utils/ConfigConstant.java | 21 + .../java/io/renren/common/utils/Constant.java | 152 + .../io/renren/common/utils/DateUtils.java | 166 + .../renren/common/utils/HttpContextUtils.java | 32 + .../java/io/renren/common/utils/IPUtils.java | 64 + .../java/io/renren/common/utils/MapUtils.java | 26 + .../io/renren/common/utils/PageUtils.java | 110 + .../java/io/renren/common/utils/Query.java | 77 + .../main/java/io/renren/common/utils/R.java | 64 + .../io/renren/common/utils/RedisKeys.java | 21 + .../io/renren/common/utils/RedisUtils.java | 99 + .../io/renren/common/utils/ShiroUtils.java | 61 + .../common/utils/SpringContextUtils.java | 51 + .../io/renren/common/validator/Assert.java | 32 + .../common/validator/ValidatorUtils.java | 54 + .../common/validator/group/AddGroup.java | 17 + .../common/validator/group/AliyunGroup.java | 17 + .../renren/common/validator/group/Group.java | 21 + .../common/validator/group/QcloudGroup.java | 17 + .../common/validator/group/QiniuGroup.java | 17 + .../common/validator/group/UpdateGroup.java | 19 + .../java/io/renren/common/xss/HTMLFilter.java | 530 + .../java/io/renren/common/xss/SQLFilter.java | 50 + .../java/io/renren/common/xss/XssFilter.java | 37 + .../xss/XssHttpServletRequestWrapper.java | 147 + .../java/io/renren/config/CorsConfig.java | 26 + .../java/io/renren/config/FilterConfig.java | 49 + .../java/io/renren/config/KaptchaConfig.java | 39 + .../io/renren/config/MybatisPlusConfig.java | 31 + .../java/io/renren/config/RedisConfig.java | 63 + .../java/io/renren/config/ShiroConfig.java | 81 + .../java/io/renren/config/SwaggerConfig.java | 61 + .../datasource/annotation/DataSource.java | 24 + .../datasource/aspect/DataSourceAspect.java | 71 + .../config/DynamicContextHolder.java | 57 + .../datasource/config/DynamicDataSource.java | 25 + .../config/DynamicDataSourceConfig.java | 63 + .../config/DynamicDataSourceFactory.java | 54 + .../properties/DataSourceProperties.java | 202 + .../DynamicDataSourceProperties.java | 33 + .../renren/modules/app/annotation/Login.java | 22 + .../modules/app/annotation/LoginUser.java | 25 + .../modules/app/config/WebMvcConfig.java | 42 + .../app/controller/AppLoginController.java | 64 + .../app/controller/AppRegisterController.java | 55 + .../app/controller/AppTestController.java | 53 + .../io/renren/modules/app/dao/UserDao.java | 23 + .../renren/modules/app/entity/UserEntity.java | 51 + .../io/renren/modules/app/form/LoginForm.java | 33 + .../renren/modules/app/form/RegisterForm.java | 33 + .../interceptor/AuthorizationInterceptor.java | 72 + ...oginUserHandlerMethodArgumentResolver.java | 53 + .../modules/app/service/UserService.java | 31 + .../app/service/impl/UserServiceImpl.java | 44 + .../io/renren/modules/app/utils/JwtUtils.java | 95 + .../modules/job/config/ScheduleConfig.java | 66 + .../job/controller/ScheduleJobController.java | 132 + .../controller/ScheduleJobLogController.java | 55 + .../modules/job/dao/ScheduleJobDao.java | 29 + .../modules/job/dao/ScheduleJobLogDao.java | 23 + .../modules/job/entity/ScheduleJobEntity.java | 74 + .../job/entity/ScheduleJobLogEntity.java | 71 + .../job/service/ScheduleJobLogService.java | 26 + .../job/service/ScheduleJobService.java | 60 + .../impl/ScheduleJobLogServiceImpl.java | 39 + .../service/impl/ScheduleJobServiceImpl.java | 131 + .../io/renren/modules/job/task/ITask.java | 24 + .../io/renren/modules/job/task/TestTask.java | 30 + .../renren/modules/job/utils/ScheduleJob.java | 81 + .../modules/job/utils/ScheduleUtils.java | 156 + .../oss/cloud/AliyunCloudStorageService.java | 62 + .../modules/oss/cloud/CloudStorageConfig.java | 94 + .../oss/cloud/CloudStorageService.java | 78 + .../renren/modules/oss/cloud/OSSFactory.java | 44 + .../oss/cloud/QcloudCloudStorageService.java | 88 + .../oss/cloud/QiniuCloudStorageService.java | 77 + .../oss/controller/SysOssController.java | 125 + .../io/renren/modules/oss/dao/SysOssDao.java | 23 + .../modules/oss/entity/SysOssEntity.java | 36 + .../modules/oss/service/SysOssService.java | 25 + .../oss/service/impl/SysOssServiceImpl.java | 35 + .../sys/controller/AbstractController.java | 31 + .../sys/controller/SysConfigController.java | 98 + .../sys/controller/SysLogController.java | 48 + .../sys/controller/SysLoginController.java | 100 + .../sys/controller/SysMenuController.java | 205 + .../sys/controller/SysRoleController.java | 129 + .../sys/controller/SysUserController.java | 155 + .../renren/modules/sys/dao/SysCaptchaDao.java | 23 + .../renren/modules/sys/dao/SysConfigDao.java | 35 + .../io/renren/modules/sys/dao/SysLogDao.java | 24 + .../io/renren/modules/sys/dao/SysMenuDao.java | 36 + .../io/renren/modules/sys/dao/SysRoleDao.java | 29 + .../modules/sys/dao/SysRoleMenuDao.java | 34 + .../io/renren/modules/sys/dao/SysUserDao.java | 41 + .../modules/sys/dao/SysUserRoleDao.java | 35 + .../modules/sys/dao/SysUserTokenDao.java | 25 + .../modules/sys/entity/SysCaptchaEntity.java | 37 + .../modules/sys/entity/SysConfigEntity.java | 33 + .../modules/sys/entity/SysLogEntity.java | 45 + .../modules/sys/entity/SysMenuEntity.java | 90 + .../modules/sys/entity/SysRoleEntity.java | 62 + .../modules/sys/entity/SysRoleMenuEntity.java | 40 + .../modules/sys/entity/SysUserEntity.java | 90 + .../modules/sys/entity/SysUserRoleEntity.java | 40 + .../sys/entity/SysUserTokenEntity.java | 40 + .../renren/modules/sys/form/PasswordForm.java | 29 + .../renren/modules/sys/form/SysLoginForm.java | 26 + .../io/renren/modules/sys/jwt/JWTFilter.java | 110 + .../io/renren/modules/sys/jwt/JWTRealm.java | 79 + .../io/renren/modules/sys/jwt/JWTToken.java | 35 + .../modules/sys/jwt/TokenGenerator.java | 52 + .../modules/sys/redis/SysConfigRedis.java | 45 + .../modules/sys/service/ShiroService.java | 34 + .../sys/service/SysCaptchaService.java | 35 + .../modules/sys/service/SysConfigService.java | 60 + .../modules/sys/service/SysLogService.java | 28 + .../modules/sys/service/SysMenuService.java | 52 + .../sys/service/SysRoleMenuService.java | 37 + .../modules/sys/service/SysRoleService.java | 39 + .../sys/service/SysUserRoleService.java | 36 + .../modules/sys/service/SysUserService.java | 66 + .../sys/service/SysUserTokenService.java | 34 + .../sys/service/impl/ShiroServiceImpl.java | 68 + .../service/impl/SysCaptchaServiceImpl.java | 71 + .../service/impl/SysConfigServiceImpl.java | 104 + .../sys/service/impl/SysLogServiceImpl.java | 39 + .../sys/service/impl/SysMenuServiceImpl.java | 140 + .../service/impl/SysRoleMenuServiceImpl.java | 60 + .../sys/service/impl/SysRoleServiceImpl.java | 124 + .../service/impl/SysUserRoleServiceImpl.java | 58 + .../sys/service/impl/SysUserServiceImpl.java | 145 + .../service/impl/SysUserTokenServiceImpl.java | 74 + .../src/main/resources/application-dev.yml | 63 + .../src/main/resources/application-prod.yml | 63 + .../src/main/resources/application-test.yml | 63 + .../src/main/resources/application.yml | 67 + renren-fast/src/main/resources/banner.txt | 5 + .../src/main/resources/logback-spring.xml | 21 + .../src/main/resources/mapper/app/UserDao.xml | 7 + .../resources/mapper/job/ScheduleJobDao.xml | 14 + .../mapper/job/ScheduleJobLogDao.xml | 6 + .../main/resources/mapper/oss/SysOssDao.xml | 7 + .../resources/mapper/sys/SysConfigDao.xml | 15 + .../main/resources/mapper/sys/SysLogDao.xml | 6 + .../main/resources/mapper/sys/SysMenuDao.xml | 14 + .../main/resources/mapper/sys/SysRoleDao.xml | 10 + .../resources/mapper/sys/SysRoleMenuDao.xml | 17 + .../main/resources/mapper/sys/SysUserDao.xml | 24 + .../resources/mapper/sys/SysUserRoleDao.xml | 16 + .../resources/mapper/sys/SysUserTokenDao.xml | 9 + .../src/main/resources/static/favicon.ico | Bin 0 -> 4286 bytes .../resources/static/swagger/css/print.css | 1 + .../resources/static/swagger/css/reset.css | 1 + .../resources/static/swagger/css/screen.css | 1 + .../resources/static/swagger/css/style.css | 1 + .../static/swagger/css/typography.css | 0 .../static/swagger/favicon-16x16.png | Bin 0 -> 445 bytes .../static/swagger/favicon-32x32.png | Bin 0 -> 1141 bytes .../static/swagger/fonts/DroidSans-Bold.ttf | Bin 0 -> 42480 bytes .../static/swagger/fonts/DroidSans.ttf | Bin 0 -> 41028 bytes .../static/swagger/images/collapse.gif | Bin 0 -> 69 bytes .../static/swagger/images/expand.gif | Bin 0 -> 73 bytes .../static/swagger/images/explorer_icons.png | Bin 0 -> 5115 bytes .../static/swagger/images/favicon-16x16.png | Bin 0 -> 445 bytes .../static/swagger/images/favicon-32x32.png | Bin 0 -> 1141 bytes .../static/swagger/images/favicon.ico | Bin 0 -> 5430 bytes .../static/swagger/images/logo_small.png | Bin 0 -> 455 bytes .../static/swagger/images/pet_store_api.png | Bin 0 -> 631 bytes .../static/swagger/images/throbber.gif | Bin 0 -> 9257 bytes .../static/swagger/images/wordnik_api.png | Bin 0 -> 670 bytes .../main/resources/static/swagger/index.html | 107 + .../main/resources/static/swagger/index.yaml | 1664 + .../main/resources/static/swagger/lang/en.js | 56 + .../static/swagger/lang/translator.js | 39 + .../resources/static/swagger/lang/zh-cn.js | 56 + .../static/swagger/lib/backbone-min.js | 1 + .../resources/static/swagger/lib/es5-shim.js | 1 + .../static/swagger/lib/handlebars-4.0.5.js | 3 + .../swagger/lib/highlight.9.1.0.pack.js | 1 + .../lib/highlight.9.1.0.pack_extended.js | 1 + .../static/swagger/lib/jquery-1.8.0.min.js | 3 + .../static/swagger/lib/jquery.ba-bbq.min.js | 1 + .../static/swagger/lib/jquery.slideto.min.js | 1 + .../static/swagger/lib/jquery.wiggle.min.js | 1 + .../static/swagger/lib/js-yaml.min.js | 2 + .../static/swagger/lib/jsoneditor.min.js | 5 + .../static/swagger/lib/lodash.min.js | 2 + .../resources/static/swagger/lib/marked.js | 1 + .../swagger/lib/object-assign-pollyfill.js | 1 + .../static/swagger/lib/sanitize-html.min.js | 4 + .../static/swagger/lib/swagger-oauth.js | 1 + .../main/resources/static/swagger/o2c.html | 20 + .../static/swagger/oauth2-redirect.html | 53 + .../static/swagger/swagger-ui-bundle.js | 105 + .../static/swagger/swagger-ui-bundle.js.map | 1 + .../swagger/swagger-ui-standalone-preset.js | 21 + .../swagger-ui-standalone-preset.js.map | 1 + .../resources/static/swagger/swagger-ui.css | 2 + .../static/swagger/swagger-ui.css.map | 1 + .../resources/static/swagger/swagger-ui.js | 25344 ++++++++++++++++ .../static/swagger/swagger-ui.js.map | 1 + .../static/swagger/swagger-ui.min.js | 15 + .../java/io/renren/DynamicDataSourceTest.java | 38 + .../src/test/java/io/renren/JwtTest.java | 24 + .../src/test/java/io/renren/RedisTest.java | 27 + .../service/DynamicDataSourceTestService.java | 57 + renren-generator/LICENSE | 674 + renren-generator/README.md | 25 + renren-generator/pom.xml | 165 + .../java/io/renren/RenrenApplication.java | 16 + .../renren/adaptor/MongoTableInfoAdaptor.java | 66 + .../main/java/io/renren/config/DbConfig.java | 69 + .../java/io/renren/config/MongoCondition.java | 18 + .../java/io/renren/config/MongoConfig.java | 92 + .../java/io/renren/config/MongoManager.java | 38 + .../io/renren/config/MongoNullCondition.java | 17 + .../controller/SysGeneratorController.java | 62 + .../main/java/io/renren/dao/GeneratorDao.java | 34 + .../io/renren/dao/MongoDBGeneratorDao.java | 56 + .../java/io/renren/dao/MySQLGeneratorDao.java | 16 + .../io/renren/dao/OracleGeneratorDao.java | 14 + .../io/renren/dao/PostgreSQLGeneratorDao.java | 14 + .../io/renren/dao/SQLServerGeneratorDao.java | 14 + .../java/io/renren/entity/ColumnEntity.java | 69 + .../java/io/renren/entity/TableEntity.java | 63 + .../renren/entity/mongo/MongoDefinition.java | 98 + .../entity/mongo/MongoGeneratorEntity.java | 50 + .../java/io/renren/entity/mongo/Type.java | 35 + .../factory/MongoDBCollectionFactory.java | 101 + .../renren/service/SysGeneratorService.java | 79 + .../main/java/io/renren/utils/Constant.java | 13 + .../main/java/io/renren/utils/DateUtils.java | 30 + .../main/java/io/renren/utils/GenUtils.java | 353 + .../java/io/renren/utils/MongoScanner.java | 301 + .../main/java/io/renren/utils/PageUtils.java | 81 + .../src/main/java/io/renren/utils/Query.java | 48 + .../src/main/java/io/renren/utils/R.java | 55 + .../java/io/renren/utils/RRException.java | 55 + .../io/renren/utils/RRExceptionHandler.java | 52 + .../src/main/resources/application.yml | 59 + .../src/main/resources/generator.properties | 65 + .../resources/mapper/MySQLGeneratorDao.xml | 23 + .../resources/mapper/OracleGeneratorDao.xml | 63 + .../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 | 61 + .../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 | 90 + .../src/main/resources/template/Dao.java.vm | 17 + .../src/main/resources/template/Dao.xml.vm | 14 + .../main/resources/template/Entity.java.vm | 35 + .../template/MongoChildrenEntity.java.vm | 29 + .../resources/template/MongoEntity.java.vm | 36 + .../main/resources/template/Service.java.vm | 20 + .../resources/template/ServiceImpl.java.vm | 29 + .../resources/template/add-or-update.vue.vm | 109 + .../src/main/resources/template/index.vue.vm | 159 + .../src/main/resources/template/menu.sql.vm | 16 + .../src/main/resources/views/generator.html | 35 + .../src/main/resources/views/index.html | 110 + .../src/main/resources/views/main.html | 29 + .../io/renren/RenrenApplicationTests.java | 16 + 416 files changed, 53664 insertions(+), 13 deletions(-) delete mode 100644 book-product/src/main/java/com/bookstore/bookmall/bookproduct/BookProductApplication.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrAttrgroupRelationController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrGroupController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/BrandController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryBrandRelationController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/CommentReplayController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/ProductAttrValueController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuImagesController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuInfoController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuSaleAttrValueController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuCommentController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuImagesController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoDescController.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrAttrgroupRelationDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrGroupDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/BrandDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryBrandRelationDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/CommentReplayDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/ProductAttrValueDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuImagesDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuInfoDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuSaleAttrValueDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuCommentDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuImagesDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDescDao.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrAttrgroupRelationEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrGroupEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/BrandEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryBrandRelationEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/CommentReplayEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/ProductAttrValueEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuImagesEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuInfoEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuSaleAttrValueEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuCommentEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuImagesEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoDescEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoEntity.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/AttrAttrgroupRelationService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/AttrGroupService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/AttrService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/BrandService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryBrandRelationService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/CommentReplayService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/ProductAttrValueService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/SkuImagesService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/SkuInfoService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/SkuSaleAttrValueService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/SpuCommentService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/SpuImagesService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoDescService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoService.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrAttrgroupRelationServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrGroupServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/BrandServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryBrandRelationServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CommentReplayServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/ProductAttrValueServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuImagesServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuInfoServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuSaleAttrValueServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuCommentServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuImagesServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoDescServiceImpl.java create mode 100644 book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoServiceImpl.java create mode 100644 book-product/src/main/resources/mapper/product/AttrAttrgroupRelationDao.xml create mode 100644 book-product/src/main/resources/mapper/product/AttrDao.xml create mode 100644 book-product/src/main/resources/mapper/product/AttrGroupDao.xml create mode 100644 book-product/src/main/resources/mapper/product/BrandDao.xml create mode 100644 book-product/src/main/resources/mapper/product/CategoryBrandRelationDao.xml create mode 100644 book-product/src/main/resources/mapper/product/CategoryDao.xml create mode 100644 book-product/src/main/resources/mapper/product/CommentReplayDao.xml create mode 100644 book-product/src/main/resources/mapper/product/ProductAttrValueDao.xml create mode 100644 book-product/src/main/resources/mapper/product/SkuImagesDao.xml create mode 100644 book-product/src/main/resources/mapper/product/SkuInfoDao.xml create mode 100644 book-product/src/main/resources/mapper/product/SkuSaleAttrValueDao.xml create mode 100644 book-product/src/main/resources/mapper/product/SpuCommentDao.xml create mode 100644 book-product/src/main/resources/mapper/product/SpuImagesDao.xml create mode 100644 book-product/src/main/resources/mapper/product/SpuInfoDao.xml create mode 100644 book-product/src/main/resources/mapper/product/SpuInfoDescDao.xml create mode 100644 mall-common/mall-common.iml create mode 100644 mall-common/pom.xml create mode 100644 renren-fast/Dockerfile create mode 100644 renren-fast/LICENSE create mode 100644 renren-fast/README.md create mode 100644 renren-fast/db/mysql.sql create mode 100644 renren-fast/db/oracle.sql create mode 100644 renren-fast/db/postgresql.sql create mode 100644 renren-fast/db/sqlserver.sql create mode 100644 renren-fast/docker-compose.yml create mode 100644 renren-fast/pom.xml create mode 100644 renren-fast/src/main/java/io/renren/RenrenApplication.java create mode 100644 renren-fast/src/main/java/io/renren/common/annotation/SysLog.java create mode 100644 renren-fast/src/main/java/io/renren/common/aspect/RedisAspect.java create mode 100644 renren-fast/src/main/java/io/renren/common/aspect/SysLogAspect.java create mode 100644 renren-fast/src/main/java/io/renren/common/exception/RRException.java create mode 100644 renren-fast/src/main/java/io/renren/common/exception/RRExceptionHandler.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/BeanFindUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/ConfigConstant.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/Constant.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/DateUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/HttpContextUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/IPUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/MapUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/PageUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/Query.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/R.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/RedisKeys.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/RedisUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/ShiroUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/utils/SpringContextUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/Assert.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/ValidatorUtils.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/group/AddGroup.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/group/AliyunGroup.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/group/Group.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/group/QcloudGroup.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/group/QiniuGroup.java create mode 100644 renren-fast/src/main/java/io/renren/common/validator/group/UpdateGroup.java create mode 100644 renren-fast/src/main/java/io/renren/common/xss/HTMLFilter.java create mode 100644 renren-fast/src/main/java/io/renren/common/xss/SQLFilter.java create mode 100644 renren-fast/src/main/java/io/renren/common/xss/XssFilter.java create mode 100644 renren-fast/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java create mode 100644 renren-fast/src/main/java/io/renren/config/CorsConfig.java create mode 100644 renren-fast/src/main/java/io/renren/config/FilterConfig.java create mode 100644 renren-fast/src/main/java/io/renren/config/KaptchaConfig.java create mode 100644 renren-fast/src/main/java/io/renren/config/MybatisPlusConfig.java create mode 100644 renren-fast/src/main/java/io/renren/config/RedisConfig.java create mode 100644 renren-fast/src/main/java/io/renren/config/ShiroConfig.java create mode 100644 renren-fast/src/main/java/io/renren/config/SwaggerConfig.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/annotation/DataSource.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/aspect/DataSourceAspect.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/config/DynamicContextHolder.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSource.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceConfig.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceFactory.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/properties/DataSourceProperties.java create mode 100644 renren-fast/src/main/java/io/renren/datasource/properties/DynamicDataSourceProperties.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/annotation/Login.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/annotation/LoginUser.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/config/WebMvcConfig.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/controller/AppLoginController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/controller/AppRegisterController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/controller/AppTestController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/dao/UserDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/entity/UserEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/form/LoginForm.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/form/RegisterForm.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/interceptor/AuthorizationInterceptor.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/resolver/LoginUserHandlerMethodArgumentResolver.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/service/UserService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/service/impl/UserServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/app/utils/JwtUtils.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/config/ScheduleConfig.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/task/ITask.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/task/TestTask.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleJob.java create mode 100644 renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/controller/SysOssController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/dao/SysOssDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/service/SysOssService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/controller/AbstractController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/controller/SysConfigController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/controller/SysLogController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/controller/SysLoginController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/controller/SysMenuController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/controller/SysRoleController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/controller/SysUserController.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysCaptchaDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysConfigDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysLogDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserRoleDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserTokenDao.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysCaptchaEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysConfigEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysLogEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserRoleEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserTokenEntity.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/form/PasswordForm.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/form/SysLoginForm.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTFilter.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTRealm.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTToken.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/jwt/TokenGenerator.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/redis/SysConfigRedis.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/ShiroService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysCaptchaService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysConfigService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysLogService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysMenuService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysUserRoleService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysUserService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/SysUserTokenService.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/ShiroServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysCaptchaServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysLogServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserRoleServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java create mode 100644 renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserTokenServiceImpl.java create mode 100644 renren-fast/src/main/resources/application-dev.yml create mode 100644 renren-fast/src/main/resources/application-prod.yml create mode 100644 renren-fast/src/main/resources/application-test.yml create mode 100644 renren-fast/src/main/resources/application.yml create mode 100644 renren-fast/src/main/resources/banner.txt create mode 100644 renren-fast/src/main/resources/logback-spring.xml create mode 100644 renren-fast/src/main/resources/mapper/app/UserDao.xml create mode 100644 renren-fast/src/main/resources/mapper/job/ScheduleJobDao.xml create mode 100644 renren-fast/src/main/resources/mapper/job/ScheduleJobLogDao.xml create mode 100644 renren-fast/src/main/resources/mapper/oss/SysOssDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysConfigDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysLogDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysMenuDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysRoleDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysRoleMenuDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysUserDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysUserRoleDao.xml create mode 100644 renren-fast/src/main/resources/mapper/sys/SysUserTokenDao.xml create mode 100644 renren-fast/src/main/resources/static/favicon.ico create mode 100644 renren-fast/src/main/resources/static/swagger/css/print.css create mode 100644 renren-fast/src/main/resources/static/swagger/css/reset.css create mode 100644 renren-fast/src/main/resources/static/swagger/css/screen.css create mode 100644 renren-fast/src/main/resources/static/swagger/css/style.css create mode 100644 renren-fast/src/main/resources/static/swagger/css/typography.css create mode 100644 renren-fast/src/main/resources/static/swagger/favicon-16x16.png create mode 100644 renren-fast/src/main/resources/static/swagger/favicon-32x32.png create mode 100644 renren-fast/src/main/resources/static/swagger/fonts/DroidSans-Bold.ttf create mode 100644 renren-fast/src/main/resources/static/swagger/fonts/DroidSans.ttf create mode 100644 renren-fast/src/main/resources/static/swagger/images/collapse.gif create mode 100644 renren-fast/src/main/resources/static/swagger/images/expand.gif create mode 100644 renren-fast/src/main/resources/static/swagger/images/explorer_icons.png create mode 100644 renren-fast/src/main/resources/static/swagger/images/favicon-16x16.png create mode 100644 renren-fast/src/main/resources/static/swagger/images/favicon-32x32.png create mode 100644 renren-fast/src/main/resources/static/swagger/images/favicon.ico create mode 100644 renren-fast/src/main/resources/static/swagger/images/logo_small.png create mode 100644 renren-fast/src/main/resources/static/swagger/images/pet_store_api.png create mode 100644 renren-fast/src/main/resources/static/swagger/images/throbber.gif create mode 100644 renren-fast/src/main/resources/static/swagger/images/wordnik_api.png create mode 100644 renren-fast/src/main/resources/static/swagger/index.html create mode 100644 renren-fast/src/main/resources/static/swagger/index.yaml create mode 100644 renren-fast/src/main/resources/static/swagger/lang/en.js create mode 100644 renren-fast/src/main/resources/static/swagger/lang/translator.js create mode 100644 renren-fast/src/main/resources/static/swagger/lang/zh-cn.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/backbone-min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/es5-shim.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/handlebars-4.0.5.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/highlight.9.1.0.pack.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/highlight.9.1.0.pack_extended.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/jquery-1.8.0.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/jquery.ba-bbq.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/jquery.slideto.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/jquery.wiggle.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/js-yaml.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/jsoneditor.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/lodash.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/marked.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/object-assign-pollyfill.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/sanitize-html.min.js create mode 100644 renren-fast/src/main/resources/static/swagger/lib/swagger-oauth.js create mode 100644 renren-fast/src/main/resources/static/swagger/o2c.html create mode 100644 renren-fast/src/main/resources/static/swagger/oauth2-redirect.html create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui-bundle.js create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui-bundle.js.map create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui-standalone-preset.js create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui-standalone-preset.js.map create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui.css create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui.css.map create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui.js create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui.js.map create mode 100644 renren-fast/src/main/resources/static/swagger/swagger-ui.min.js create mode 100644 renren-fast/src/test/java/io/renren/DynamicDataSourceTest.java create mode 100644 renren-fast/src/test/java/io/renren/JwtTest.java create mode 100644 renren-fast/src/test/java/io/renren/RedisTest.java create mode 100644 renren-fast/src/test/java/io/renren/service/DynamicDataSourceTestService.java create mode 100644 renren-generator/LICENSE create mode 100644 renren-generator/README.md create mode 100644 renren-generator/pom.xml create mode 100644 renren-generator/src/main/java/io/renren/RenrenApplication.java create mode 100644 renren-generator/src/main/java/io/renren/adaptor/MongoTableInfoAdaptor.java create mode 100644 renren-generator/src/main/java/io/renren/config/DbConfig.java create mode 100644 renren-generator/src/main/java/io/renren/config/MongoCondition.java create mode 100644 renren-generator/src/main/java/io/renren/config/MongoConfig.java create mode 100644 renren-generator/src/main/java/io/renren/config/MongoManager.java create mode 100644 renren-generator/src/main/java/io/renren/config/MongoNullCondition.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/MongoDBGeneratorDao.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/entity/mongo/MongoDefinition.java create mode 100644 renren-generator/src/main/java/io/renren/entity/mongo/MongoGeneratorEntity.java create mode 100644 renren-generator/src/main/java/io/renren/entity/mongo/Type.java create mode 100644 renren-generator/src/main/java/io/renren/factory/MongoDBCollectionFactory.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/Constant.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/MongoScanner.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/RRException.java create mode 100644 renren-generator/src/main/java/io/renren/utils/RRExceptionHandler.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/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/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/MongoChildrenEntity.java.vm create mode 100644 renren-generator/src/main/resources/template/MongoEntity.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/menu.sql.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 create mode 100644 renren-generator/src/test/java/io/renren/RenrenApplicationTests.java diff --git a/book-product/pom.xml b/book-product/pom.xml index 9a40a06..d9a2231 100644 --- a/book-product/pom.xml +++ b/book-product/pom.xml @@ -32,6 +32,12 @@ 2025.0.0 + + com.bookstore.bookmall + mall-common + 0.0.1-SNAPSHOT + + org.springframework.boot spring-boot-starter-web diff --git a/book-product/src/main/java/com/bookstore/bookmall/bookproduct/BookProductApplication.java b/book-product/src/main/java/com/bookstore/bookmall/bookproduct/BookProductApplication.java deleted file mode 100644 index a0698e4..0000000 --- a/book-product/src/main/java/com/bookstore/bookmall/bookproduct/BookProductApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.bookstore.bookmall.bookproduct; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class BookProductApplication { - - public static void main(String[] args) { - SpringApplication.run(BookProductApplication.class, args); - } - -} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrAttrgroupRelationController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrAttrgroupRelationController.java new file mode 100644 index 0000000..e27e483 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrAttrgroupRelationController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.AttrAttrgroupRelationEntity; +import com.bookstore.bookmall.product.service.AttrAttrgroupRelationService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 属性&属性分组关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/attrattrgrouprelation") +public class AttrAttrgroupRelationController { + @Autowired + private AttrAttrgroupRelationService attrAttrgroupRelationService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:attrattrgrouprelation:list") + public R list(@RequestParam Map params){ + PageUtils page = attrAttrgroupRelationService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:attrattrgrouprelation:info") //shiro的权限注解 + public R info(@PathVariable("id") Long id){ + AttrAttrgroupRelationEntity attrAttrgroupRelation = attrAttrgroupRelationService.getById(id); + + return R.ok().put("attrAttrgroupRelation", attrAttrgroupRelation); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:attrattrgrouprelation:save") + public R save(@RequestBody AttrAttrgroupRelationEntity attrAttrgroupRelation){ + attrAttrgroupRelationService.save(attrAttrgroupRelation); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:attrattrgrouprelation:update") + public R update(@RequestBody AttrAttrgroupRelationEntity attrAttrgroupRelation){ + attrAttrgroupRelationService.updateById(attrAttrgroupRelation); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:attrattrgrouprelation:delete") + public R delete(@RequestBody Long[] ids){ + attrAttrgroupRelationService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrController.java new file mode 100644 index 0000000..bbb19b4 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.AttrEntity; +import com.bookstore.bookmall.product.service.AttrService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 商品属性 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/attr") +public class AttrController { + @Autowired + private AttrService attrService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:attr:list") + public R list(@RequestParam Map params){ + PageUtils page = attrService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{attrId}") + @RequiresPermissions("product:attr:info") + public R info(@PathVariable("attrId") Long attrId){ + AttrEntity attr = attrService.getById(attrId); + + return R.ok().put("attr", attr); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:attr:save") + public R save(@RequestBody AttrEntity attr){ + attrService.save(attr); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:attr:update") + public R update(@RequestBody AttrEntity attr){ + attrService.updateById(attr); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:attr:delete") + public R delete(@RequestBody Long[] attrIds){ + attrService.removeByIds(Arrays.asList(attrIds)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrGroupController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrGroupController.java new file mode 100644 index 0000000..1a8d6b5 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/AttrGroupController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.AttrGroupEntity; +import com.bookstore.bookmall.product.service.AttrGroupService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 属性分组 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/attrgroup") +public class AttrGroupController { + @Autowired + private AttrGroupService attrGroupService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:attrgroup:list") + public R list(@RequestParam Map params){ + PageUtils page = attrGroupService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{attrGroupId}") + @RequiresPermissions("product:attrgroup:info") + public R info(@PathVariable("attrGroupId") Long attrGroupId){ + AttrGroupEntity attrGroup = attrGroupService.getById(attrGroupId); + + return R.ok().put("attrGroup", attrGroup); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:attrgroup:save") + public R save(@RequestBody AttrGroupEntity attrGroup){ + attrGroupService.save(attrGroup); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:attrgroup:update") + public R update(@RequestBody AttrGroupEntity attrGroup){ + attrGroupService.updateById(attrGroup); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:attrgroup:delete") + public R delete(@RequestBody Long[] attrGroupIds){ + attrGroupService.removeByIds(Arrays.asList(attrGroupIds)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/BrandController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/BrandController.java new file mode 100644 index 0000000..0b5384a --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/BrandController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.BrandEntity; +import com.bookstore.bookmall.product.service.BrandService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 品牌 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/brand") +public class BrandController { + @Autowired + private BrandService brandService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:brand:list") + public R list(@RequestParam Map params){ + PageUtils page = brandService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{brandId}") + @RequiresPermissions("product:brand:info") + public R info(@PathVariable("brandId") Long brandId){ + BrandEntity brand = brandService.getById(brandId); + + return R.ok().put("brand", brand); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:brand:save") + public R save(@RequestBody BrandEntity brand){ + brandService.save(brand); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:brand:update") + public R update(@RequestBody BrandEntity brand){ + brandService.updateById(brand); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:brand:delete") + public R delete(@RequestBody Long[] brandIds){ + brandService.removeByIds(Arrays.asList(brandIds)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryBrandRelationController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryBrandRelationController.java new file mode 100644 index 0000000..3527901 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryBrandRelationController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.CategoryBrandRelationEntity; +import com.bookstore.bookmall.product.service.CategoryBrandRelationService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 品牌分类关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/categorybrandrelation") +public class CategoryBrandRelationController { + @Autowired + private CategoryBrandRelationService categoryBrandRelationService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:categorybrandrelation:list") + public R list(@RequestParam Map params){ + PageUtils page = categoryBrandRelationService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:categorybrandrelation:info") + public R info(@PathVariable("id") Long id){ + CategoryBrandRelationEntity categoryBrandRelation = categoryBrandRelationService.getById(id); + + return R.ok().put("categoryBrandRelation", categoryBrandRelation); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:categorybrandrelation:save") + public R save(@RequestBody CategoryBrandRelationEntity categoryBrandRelation){ + categoryBrandRelationService.save(categoryBrandRelation); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:categorybrandrelation:update") + public R update(@RequestBody CategoryBrandRelationEntity categoryBrandRelation){ + categoryBrandRelationService.updateById(categoryBrandRelation); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:categorybrandrelation:delete") + public R delete(@RequestBody Long[] ids){ + categoryBrandRelationService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryController.java new file mode 100644 index 0000000..0543ce0 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/CategoryController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.CategoryEntity; +import com.bookstore.bookmall.product.service.CategoryService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 商品三级分类 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/category") +public class CategoryController { + @Autowired + private CategoryService categoryService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:category:list") + public R list(@RequestParam Map params){ + PageUtils page = categoryService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{catId}") + @RequiresPermissions("product:category:info") + public R info(@PathVariable("catId") Long catId){ + CategoryEntity category = categoryService.getById(catId); + + return R.ok().put("category", category); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:category:save") + public R save(@RequestBody CategoryEntity category){ + categoryService.save(category); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:category:update") + public R update(@RequestBody CategoryEntity category){ + categoryService.updateById(category); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:category:delete") + public R delete(@RequestBody Long[] catIds){ + categoryService.removeByIds(Arrays.asList(catIds)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/CommentReplayController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/CommentReplayController.java new file mode 100644 index 0000000..3629888 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/CommentReplayController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.CommentReplayEntity; +import com.bookstore.bookmall.product.service.CommentReplayService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 商品评价回复关系 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/commentreplay") +public class CommentReplayController { + @Autowired + private CommentReplayService commentReplayService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:commentreplay:list") + public R list(@RequestParam Map params){ + PageUtils page = commentReplayService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:commentreplay:info") + public R info(@PathVariable("id") Long id){ + CommentReplayEntity commentReplay = commentReplayService.getById(id); + + return R.ok().put("commentReplay", commentReplay); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:commentreplay:save") + public R save(@RequestBody CommentReplayEntity commentReplay){ + commentReplayService.save(commentReplay); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:commentreplay:update") + public R update(@RequestBody CommentReplayEntity commentReplay){ + commentReplayService.updateById(commentReplay); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:commentreplay:delete") + public R delete(@RequestBody Long[] ids){ + commentReplayService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/ProductAttrValueController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/ProductAttrValueController.java new file mode 100644 index 0000000..4f677d6 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/ProductAttrValueController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.ProductAttrValueEntity; +import com.bookstore.bookmall.product.service.ProductAttrValueService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * spu属性值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/productattrvalue") +public class ProductAttrValueController { + @Autowired + private ProductAttrValueService productAttrValueService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:productattrvalue:list") + public R list(@RequestParam Map params){ + PageUtils page = productAttrValueService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:productattrvalue:info") + public R info(@PathVariable("id") Long id){ + ProductAttrValueEntity productAttrValue = productAttrValueService.getById(id); + + return R.ok().put("productAttrValue", productAttrValue); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:productattrvalue:save") + public R save(@RequestBody ProductAttrValueEntity productAttrValue){ + productAttrValueService.save(productAttrValue); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:productattrvalue:update") + public R update(@RequestBody ProductAttrValueEntity productAttrValue){ + productAttrValueService.updateById(productAttrValue); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:productattrvalue:delete") + public R delete(@RequestBody Long[] ids){ + productAttrValueService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuImagesController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuImagesController.java new file mode 100644 index 0000000..015e204 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuImagesController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.SkuImagesEntity; +import com.bookstore.bookmall.product.service.SkuImagesService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * sku图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/skuimages") +public class SkuImagesController { + @Autowired + private SkuImagesService skuImagesService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:skuimages:list") + public R list(@RequestParam Map params){ + PageUtils page = skuImagesService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:skuimages:info") + public R info(@PathVariable("id") Long id){ + SkuImagesEntity skuImages = skuImagesService.getById(id); + + return R.ok().put("skuImages", skuImages); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:skuimages:save") + public R save(@RequestBody SkuImagesEntity skuImages){ + skuImagesService.save(skuImages); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:skuimages:update") + public R update(@RequestBody SkuImagesEntity skuImages){ + skuImagesService.updateById(skuImages); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:skuimages:delete") + public R delete(@RequestBody Long[] ids){ + skuImagesService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuInfoController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuInfoController.java new file mode 100644 index 0000000..a810b33 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuInfoController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.SkuInfoEntity; +import com.bookstore.bookmall.product.service.SkuInfoService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * sku信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/skuinfo") +public class SkuInfoController { + @Autowired + private SkuInfoService skuInfoService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:skuinfo:list") + public R list(@RequestParam Map params){ + PageUtils page = skuInfoService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{skuId}") + @RequiresPermissions("product:skuinfo:info") + public R info(@PathVariable("skuId") Long skuId){ + SkuInfoEntity skuInfo = skuInfoService.getById(skuId); + + return R.ok().put("skuInfo", skuInfo); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:skuinfo:save") + public R save(@RequestBody SkuInfoEntity skuInfo){ + skuInfoService.save(skuInfo); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:skuinfo:update") + public R update(@RequestBody SkuInfoEntity skuInfo){ + skuInfoService.updateById(skuInfo); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:skuinfo:delete") + public R delete(@RequestBody Long[] skuIds){ + skuInfoService.removeByIds(Arrays.asList(skuIds)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuSaleAttrValueController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuSaleAttrValueController.java new file mode 100644 index 0000000..7cd7d0c --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SkuSaleAttrValueController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.SkuSaleAttrValueEntity; +import com.bookstore.bookmall.product.service.SkuSaleAttrValueService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * sku销售属性&值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/skusaleattrvalue") +public class SkuSaleAttrValueController { + @Autowired + private SkuSaleAttrValueService skuSaleAttrValueService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:skusaleattrvalue:list") + public R list(@RequestParam Map params){ + PageUtils page = skuSaleAttrValueService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:skusaleattrvalue:info") + public R info(@PathVariable("id") Long id){ + SkuSaleAttrValueEntity skuSaleAttrValue = skuSaleAttrValueService.getById(id); + + return R.ok().put("skuSaleAttrValue", skuSaleAttrValue); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:skusaleattrvalue:save") + public R save(@RequestBody SkuSaleAttrValueEntity skuSaleAttrValue){ + skuSaleAttrValueService.save(skuSaleAttrValue); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:skusaleattrvalue:update") + public R update(@RequestBody SkuSaleAttrValueEntity skuSaleAttrValue){ + skuSaleAttrValueService.updateById(skuSaleAttrValue); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:skusaleattrvalue:delete") + public R delete(@RequestBody Long[] ids){ + skuSaleAttrValueService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuCommentController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuCommentController.java new file mode 100644 index 0000000..ec087df --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuCommentController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.SpuCommentEntity; +import com.bookstore.bookmall.product.service.SpuCommentService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * 商品评价 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/spucomment") +public class SpuCommentController { + @Autowired + private SpuCommentService spuCommentService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:spucomment:list") + public R list(@RequestParam Map params){ + PageUtils page = spuCommentService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:spucomment:info") + public R info(@PathVariable("id") Long id){ + SpuCommentEntity spuComment = spuCommentService.getById(id); + + return R.ok().put("spuComment", spuComment); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:spucomment:save") + public R save(@RequestBody SpuCommentEntity spuComment){ + spuCommentService.save(spuComment); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:spucomment:update") + public R update(@RequestBody SpuCommentEntity spuComment){ + spuCommentService.updateById(spuComment); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:spucomment:delete") + public R delete(@RequestBody Long[] ids){ + spuCommentService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuImagesController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuImagesController.java new file mode 100644 index 0000000..e090fc3 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuImagesController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.SpuImagesEntity; +import com.bookstore.bookmall.product.service.SpuImagesService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * spu图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/spuimages") +public class SpuImagesController { + @Autowired + private SpuImagesService spuImagesService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:spuimages:list") + public R list(@RequestParam Map params){ + PageUtils page = spuImagesService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:spuimages:info") + public R info(@PathVariable("id") Long id){ + SpuImagesEntity spuImages = spuImagesService.getById(id); + + return R.ok().put("spuImages", spuImages); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:spuimages:save") + public R save(@RequestBody SpuImagesEntity spuImages){ + spuImagesService.save(spuImages); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:spuimages:update") + public R update(@RequestBody SpuImagesEntity spuImages){ + spuImagesService.updateById(spuImages); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:spuimages:delete") + public R delete(@RequestBody Long[] ids){ + spuImagesService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoController.java new file mode 100644 index 0000000..e128573 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.SpuInfoEntity; +import com.bookstore.bookmall.product.service.SpuInfoService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * spu信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/spuinfo") +public class SpuInfoController { + @Autowired + private SpuInfoService spuInfoService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:spuinfo:list") + public R list(@RequestParam Map params){ + PageUtils page = spuInfoService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{id}") + @RequiresPermissions("product:spuinfo:info") + public R info(@PathVariable("id") Long id){ + SpuInfoEntity spuInfo = spuInfoService.getById(id); + + return R.ok().put("spuInfo", spuInfo); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:spuinfo:save") + public R save(@RequestBody SpuInfoEntity spuInfo){ + spuInfoService.save(spuInfo); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:spuinfo:update") + public R update(@RequestBody SpuInfoEntity spuInfo){ + spuInfoService.updateById(spuInfo); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:spuinfo:delete") + public R delete(@RequestBody Long[] ids){ + spuInfoService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoDescController.java b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoDescController.java new file mode 100644 index 0000000..b3a7208 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/controller/SpuInfoDescController.java @@ -0,0 +1,90 @@ +package com.bookstore.bookmall.product.controller; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.bookstore.bookmall.product.entity.SpuInfoDescEntity; +import com.bookstore.bookmall.product.service.SpuInfoDescService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.R; + + + +/** + * spu信息介绍 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@RestController +@RequestMapping("product/spuinfodesc") +public class SpuInfoDescController { + @Autowired + private SpuInfoDescService spuInfoDescService; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("product:spuinfodesc:list") + public R list(@RequestParam Map params){ + PageUtils page = spuInfoDescService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{spuId}") + @RequiresPermissions("product:spuinfodesc:info") + public R info(@PathVariable("spuId") Long spuId){ + SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getById(spuId); + + return R.ok().put("spuInfoDesc", spuInfoDesc); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("product:spuinfodesc:save") + public R save(@RequestBody SpuInfoDescEntity spuInfoDesc){ + spuInfoDescService.save(spuInfoDesc); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("product:spuinfodesc:update") + public R update(@RequestBody SpuInfoDescEntity spuInfoDesc){ + spuInfoDescService.updateById(spuInfoDesc); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("product:spuinfodesc:delete") + public R delete(@RequestBody Long[] spuIds){ + spuInfoDescService.removeByIds(Arrays.asList(spuIds)); + + return R.ok(); + } + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrAttrgroupRelationDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrAttrgroupRelationDao.java new file mode 100644 index 0000000..1ad3246 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrAttrgroupRelationDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.AttrAttrgroupRelationEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 属性&属性分组关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface AttrAttrgroupRelationDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrDao.java new file mode 100644 index 0000000..bf1a6fa --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.AttrEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 商品属性 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface AttrDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrGroupDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrGroupDao.java new file mode 100644 index 0000000..2de9559 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/AttrGroupDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.AttrGroupEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 属性分组 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface AttrGroupDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/BrandDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/BrandDao.java new file mode 100644 index 0000000..4eb94b3 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/BrandDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.BrandEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 品牌 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface BrandDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryBrandRelationDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryBrandRelationDao.java new file mode 100644 index 0000000..62e97bf --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryBrandRelationDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.CategoryBrandRelationEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 品牌分类关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface CategoryBrandRelationDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryDao.java new file mode 100644 index 0000000..7ae997d --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/CategoryDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.CategoryEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 商品三级分类 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface CategoryDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/CommentReplayDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/CommentReplayDao.java new file mode 100644 index 0000000..5892faa --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/CommentReplayDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.CommentReplayEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 商品评价回复关系 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface CommentReplayDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/ProductAttrValueDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/ProductAttrValueDao.java new file mode 100644 index 0000000..13ed205 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/ProductAttrValueDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.ProductAttrValueEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * spu属性值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface ProductAttrValueDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuImagesDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuImagesDao.java new file mode 100644 index 0000000..83c1785 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuImagesDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.SkuImagesEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * sku图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface SkuImagesDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuInfoDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuInfoDao.java new file mode 100644 index 0000000..06c790f --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuInfoDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.SkuInfoEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * sku信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface SkuInfoDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuSaleAttrValueDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuSaleAttrValueDao.java new file mode 100644 index 0000000..acacba8 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SkuSaleAttrValueDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.SkuSaleAttrValueEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * sku销售属性&值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface SkuSaleAttrValueDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuCommentDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuCommentDao.java new file mode 100644 index 0000000..d258828 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuCommentDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.SpuCommentEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 商品评价 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface SpuCommentDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuImagesDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuImagesDao.java new file mode 100644 index 0000000..21d4c1c --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuImagesDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.SpuImagesEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * spu图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface SpuImagesDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDao.java new file mode 100644 index 0000000..85f9c55 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.SpuInfoEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * spu信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface SpuInfoDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDescDao.java b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDescDao.java new file mode 100644 index 0000000..da7fe35 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/dao/SpuInfoDescDao.java @@ -0,0 +1,17 @@ +package com.bookstore.bookmall.product.dao; + +import com.bookstore.bookmall.product.entity.SpuInfoDescEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * spu信息介绍 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Mapper +public interface SpuInfoDescDao extends BaseMapper { + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrAttrgroupRelationEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrAttrgroupRelationEntity.java new file mode 100644 index 0000000..c2cf946 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrAttrgroupRelationEntity.java @@ -0,0 +1,40 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 属性&属性分组关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_attr_attrgroup_relation") +public class AttrAttrgroupRelationEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * 属性id + */ + private Long attrId; + /** + * 属性分组id + */ + private Long attrGroupId; + /** + * 属性组内排序 + */ + private Integer attrSort; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrEntity.java new file mode 100644 index 0000000..d7d9e73 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrEntity.java @@ -0,0 +1,64 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 商品属性 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_attr") +public class AttrEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 属性id + */ + @TableId + private Long attrId; + /** + * 属性名 + */ + private String attrName; + /** + * 是否需要检索[0-不需要,1-需要] + */ + private Integer searchType; + /** + * 值类型[0-为单个值,1-可以选择多个值] + */ + private Integer valueType; + /** + * 属性图标 + */ + private String icon; + /** + * 可选值列表[用逗号分隔] + */ + private String valueSelect; + /** + * 属性类型[0-销售属性,1-基本属性,2-既是销售属性又是基本属性] + */ + private Integer attrType; + /** + * 启用状态[0 - 禁用,1 - 启用] + */ + private Long enable; + /** + * 所属分类 + */ + private Long catelogId; + /** + * 快速展示【是否展示在介绍上;0-否 1-是】,在sku中仍然可以调整 + */ + private Integer showDesc; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrGroupEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrGroupEntity.java new file mode 100644 index 0000000..985b5a5 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/AttrGroupEntity.java @@ -0,0 +1,48 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 属性分组 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_attr_group") +public class AttrGroupEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 分组id + */ + @TableId + private Long attrGroupId; + /** + * 组名 + */ + private String attrGroupName; + /** + * 排序 + */ + private Integer sort; + /** + * 描述 + */ + private String descript; + /** + * 组图标 + */ + private String icon; + /** + * 所属分类id + */ + private Long catelogId; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/BrandEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/BrandEntity.java new file mode 100644 index 0000000..d7d98f0 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/BrandEntity.java @@ -0,0 +1,52 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 品牌 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_brand") +public class BrandEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 品牌id + */ + @TableId + private Long brandId; + /** + * 品牌名 + */ + private String name; + /** + * 品牌logo地址 + */ + private String logo; + /** + * 介绍 + */ + private String descript; + /** + * 显示状态[0-不显示;1-显示] + */ + private Integer showStatus; + /** + * 检索首字母 + */ + private String firstLetter; + /** + * 排序 + */ + private Integer sort; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryBrandRelationEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryBrandRelationEntity.java new file mode 100644 index 0000000..5952863 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryBrandRelationEntity.java @@ -0,0 +1,44 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 品牌分类关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_category_brand_relation") +public class CategoryBrandRelationEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * + */ + @TableId + private Long id; + /** + * 品牌id + */ + private Long brandId; + /** + * 分类id + */ + private Long catelogId; + /** + * + */ + private String brandName; + /** + * + */ + private String catelogName; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryEntity.java new file mode 100644 index 0000000..4bd98d3 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/CategoryEntity.java @@ -0,0 +1,60 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 商品三级分类 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_category") +public class CategoryEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 分类id + */ + @TableId + private Long catId; + /** + * 分类名称 + */ + private String name; + /** + * 父分类id + */ + private Long parentCid; + /** + * 层级 + */ + private Integer catLevel; + /** + * 是否显示[0-不显示,1显示] + */ + private Integer showStatus; + /** + * 排序 + */ + private Integer sort; + /** + * 图标地址 + */ + private String icon; + /** + * 计量单位 + */ + private String productUnit; + /** + * 商品数量 + */ + private Integer productCount; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/CommentReplayEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/CommentReplayEntity.java new file mode 100644 index 0000000..7148dc2 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/CommentReplayEntity.java @@ -0,0 +1,36 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 商品评价回复关系 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_comment_replay") +public class CommentReplayEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * 评论id + */ + private Long commentId; + /** + * 回复id + */ + private Long replyId; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/ProductAttrValueEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/ProductAttrValueEntity.java new file mode 100644 index 0000000..fd6fded --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/ProductAttrValueEntity.java @@ -0,0 +1,52 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * spu属性值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_product_attr_value") +public class ProductAttrValueEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * 商品id + */ + private Long spuId; + /** + * 属性id + */ + private Long attrId; + /** + * 属性名 + */ + private String attrName; + /** + * 属性值 + */ + private String attrValue; + /** + * 顺序 + */ + private Integer attrSort; + /** + * 快速展示【是否展示在介绍上;0-否 1-是】 + */ + private Integer quickShow; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuImagesEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuImagesEntity.java new file mode 100644 index 0000000..531c775 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuImagesEntity.java @@ -0,0 +1,44 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * sku图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_sku_images") +public class SkuImagesEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * sku_id + */ + private Long skuId; + /** + * 图片地址 + */ + private String imgUrl; + /** + * 排序 + */ + private Integer imgSort; + /** + * 默认图[0 - 不是默认图,1 - 是默认图] + */ + private Integer defaultImg; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuInfoEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuInfoEntity.java new file mode 100644 index 0000000..733ec4a --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuInfoEntity.java @@ -0,0 +1,69 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.math.BigDecimal; +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * sku信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_sku_info") +public class SkuInfoEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * skuId + */ + @TableId + private Long skuId; + /** + * spuId + */ + private Long spuId; + /** + * sku名称 + */ + private String skuName; + /** + * sku介绍描述 + */ + private String skuDesc; + /** + * 所属分类id + */ + private Long catalogId; + /** + * 品牌id + */ + private Long brandId; + /** + * 默认图片 + */ + private String skuDefaultImg; + /** + * 标题 + */ + private String skuTitle; + /** + * 副标题 + */ + private String skuSubtitle; + /** + * 价格 + */ + private BigDecimal price; + /** + * 销量 + */ + private Long saleCount; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuSaleAttrValueEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuSaleAttrValueEntity.java new file mode 100644 index 0000000..4601f13 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SkuSaleAttrValueEntity.java @@ -0,0 +1,48 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * sku销售属性&值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_sku_sale_attr_value") +public class SkuSaleAttrValueEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * sku_id + */ + private Long skuId; + /** + * attr_id + */ + private Long attrId; + /** + * 销售属性名 + */ + private String attrName; + /** + * 销售属性值 + */ + private String attrValue; + /** + * 顺序 + */ + private Integer attrSort; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuCommentEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuCommentEntity.java new file mode 100644 index 0000000..fe92461 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuCommentEntity.java @@ -0,0 +1,88 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 商品评价 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_spu_comment") +public class SpuCommentEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * sku_id + */ + private Long skuId; + /** + * spu_id + */ + private Long spuId; + /** + * 商品名字 + */ + private String spuName; + /** + * 会员昵称 + */ + private String memberNickName; + /** + * 星级 + */ + private Integer star; + /** + * 会员ip + */ + private String memberIp; + /** + * 创建时间 + */ + private Date createTime; + /** + * 显示状态[0-不显示,1-显示] + */ + private Integer showStatus; + /** + * 购买时属性组合 + */ + private String spuAttributes; + /** + * 点赞数 + */ + private Integer likesCount; + /** + * 回复数 + */ + private Integer replyCount; + /** + * 评论图片/视频[json数据;[{type:文件类型,url:资源路径}]] + */ + private String resources; + /** + * 内容 + */ + private String content; + /** + * 用户头像 + */ + private String memberIcon; + /** + * 评论类型[0 - 对商品的直接评论,1 - 对评论的回复] + */ + private Integer commentType; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuImagesEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuImagesEntity.java new file mode 100644 index 0000000..740708c --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuImagesEntity.java @@ -0,0 +1,48 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * spu图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_spu_images") +public class SpuImagesEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId + private Long id; + /** + * spu_id + */ + private Long spuId; + /** + * 图片名 + */ + private String imgName; + /** + * 图片地址 + */ + private String imgUrl; + /** + * 顺序 + */ + private Integer imgSort; + /** + * 是否默认图 + */ + private Integer defaultImg; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoDescEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoDescEntity.java new file mode 100644 index 0000000..2343bf4 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoDescEntity.java @@ -0,0 +1,32 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * spu信息介绍 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_spu_info_desc") +public class SpuInfoDescEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 商品id + */ + @TableId + private Long spuId; + /** + * 商品介绍 + */ + private String decript; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoEntity.java b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoEntity.java new file mode 100644 index 0000000..3ff1f40 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/entity/SpuInfoEntity.java @@ -0,0 +1,61 @@ +package com.bookstore.bookmall.product.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.math.BigDecimal; +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * spu信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +@Data +@TableName("pms_spu_info") +public class SpuInfoEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 商品id + */ + @TableId + private Long id; + /** + * 商品名称 + */ + private String spuName; + /** + * 商品描述 + */ + private String spuDescription; + /** + * 所属分类id + */ + private Long catalogId; + /** + * 品牌id + */ + private Long brandId; + /** + * + */ + private BigDecimal weight; + /** + * 上架状态[0 - 下架,1 - 上架] + */ + private Integer publishStatus; + /** + * + */ + private Date createTime; + /** + * + */ + private Date updateTime; + +} diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrAttrgroupRelationService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrAttrgroupRelationService.java new file mode 100644 index 0000000..d5a1247 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrAttrgroupRelationService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.AttrAttrgroupRelationEntity; + +import java.util.Map; + +/** + * 属性&属性分组关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface AttrAttrgroupRelationService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrGroupService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrGroupService.java new file mode 100644 index 0000000..2931b83 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrGroupService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.AttrGroupEntity; + +import java.util.Map; + +/** + * 属性分组 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface AttrGroupService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrService.java new file mode 100644 index 0000000..c908ddb --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/AttrService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.AttrEntity; + +import java.util.Map; + +/** + * 商品属性 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface AttrService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/BrandService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/BrandService.java new file mode 100644 index 0000000..06dcc74 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/BrandService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.BrandEntity; + +import java.util.Map; + +/** + * 品牌 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface BrandService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryBrandRelationService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryBrandRelationService.java new file mode 100644 index 0000000..e81d8fe --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryBrandRelationService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.CategoryBrandRelationEntity; + +import java.util.Map; + +/** + * 品牌分类关联 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface CategoryBrandRelationService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryService.java new file mode 100644 index 0000000..22b6a72 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/CategoryService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.CategoryEntity; + +import java.util.Map; + +/** + * 商品三级分类 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface CategoryService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/CommentReplayService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/CommentReplayService.java new file mode 100644 index 0000000..9ad49b0 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/CommentReplayService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.CommentReplayEntity; + +import java.util.Map; + +/** + * 商品评价回复关系 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface CommentReplayService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/ProductAttrValueService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/ProductAttrValueService.java new file mode 100644 index 0000000..5347bc6 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/ProductAttrValueService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.ProductAttrValueEntity; + +import java.util.Map; + +/** + * spu属性值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface ProductAttrValueService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuImagesService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuImagesService.java new file mode 100644 index 0000000..9329943 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuImagesService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.SkuImagesEntity; + +import java.util.Map; + +/** + * sku图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface SkuImagesService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuInfoService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuInfoService.java new file mode 100644 index 0000000..6ef893d --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuInfoService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.SkuInfoEntity; + +import java.util.Map; + +/** + * sku信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface SkuInfoService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuSaleAttrValueService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuSaleAttrValueService.java new file mode 100644 index 0000000..d82d87b --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/SkuSaleAttrValueService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.SkuSaleAttrValueEntity; + +import java.util.Map; + +/** + * sku销售属性&值 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface SkuSaleAttrValueService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuCommentService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuCommentService.java new file mode 100644 index 0000000..012b723 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuCommentService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.SpuCommentEntity; + +import java.util.Map; + +/** + * 商品评价 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface SpuCommentService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuImagesService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuImagesService.java new file mode 100644 index 0000000..ca43f3d --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuImagesService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.SpuImagesEntity; + +import java.util.Map; + +/** + * spu图片 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface SpuImagesService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoDescService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoDescService.java new file mode 100644 index 0000000..31e334e --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoDescService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.SpuInfoDescEntity; + +import java.util.Map; + +/** + * spu信息介绍 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface SpuInfoDescService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoService.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoService.java new file mode 100644 index 0000000..df0d8aa --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/SpuInfoService.java @@ -0,0 +1,20 @@ +package com.bookstore.bookmall.product.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.bookmall.product.entity.SpuInfoEntity; + +import java.util.Map; + +/** + * spu信息 + * + * @author dy + * @email 2073699128@qq.com + * @date 2025-07-06 21:28:01 + */ +public interface SpuInfoService extends IService { + + PageUtils queryPage(Map params); +} + diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrAttrgroupRelationServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrAttrgroupRelationServiceImpl.java new file mode 100644 index 0000000..2b8d133 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrAttrgroupRelationServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.AttrAttrgroupRelationDao; +import com.bookstore.bookmall.product.entity.AttrAttrgroupRelationEntity; +import com.bookstore.bookmall.product.service.AttrAttrgroupRelationService; + + +@Service("attrAttrgroupRelationService") +public class AttrAttrgroupRelationServiceImpl extends ServiceImpl implements AttrAttrgroupRelationService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrGroupServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrGroupServiceImpl.java new file mode 100644 index 0000000..fc53d0b --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrGroupServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.AttrGroupDao; +import com.bookstore.bookmall.product.entity.AttrGroupEntity; +import com.bookstore.bookmall.product.service.AttrGroupService; + + +@Service("attrGroupService") +public class AttrGroupServiceImpl extends ServiceImpl implements AttrGroupService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrServiceImpl.java new file mode 100644 index 0000000..d02c43a --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/AttrServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.AttrDao; +import com.bookstore.bookmall.product.entity.AttrEntity; +import com.bookstore.bookmall.product.service.AttrService; + + +@Service("attrService") +public class AttrServiceImpl extends ServiceImpl implements AttrService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/BrandServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/BrandServiceImpl.java new file mode 100644 index 0000000..1934de7 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/BrandServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.BrandDao; +import com.bookstore.bookmall.product.entity.BrandEntity; +import com.bookstore.bookmall.product.service.BrandService; + + +@Service("brandService") +public class BrandServiceImpl extends ServiceImpl implements BrandService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryBrandRelationServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryBrandRelationServiceImpl.java new file mode 100644 index 0000000..15579e6 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryBrandRelationServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.CategoryBrandRelationDao; +import com.bookstore.bookmall.product.entity.CategoryBrandRelationEntity; +import com.bookstore.bookmall.product.service.CategoryBrandRelationService; + + +@Service("categoryBrandRelationService") +public class CategoryBrandRelationServiceImpl extends ServiceImpl implements CategoryBrandRelationService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryServiceImpl.java new file mode 100644 index 0000000..5b555e8 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CategoryServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.CategoryDao; +import com.bookstore.bookmall.product.entity.CategoryEntity; +import com.bookstore.bookmall.product.service.CategoryService; + + +@Service("categoryService") +public class CategoryServiceImpl extends ServiceImpl implements CategoryService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CommentReplayServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CommentReplayServiceImpl.java new file mode 100644 index 0000000..ebfe3d3 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/CommentReplayServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.CommentReplayDao; +import com.bookstore.bookmall.product.entity.CommentReplayEntity; +import com.bookstore.bookmall.product.service.CommentReplayService; + + +@Service("commentReplayService") +public class CommentReplayServiceImpl extends ServiceImpl implements CommentReplayService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/ProductAttrValueServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/ProductAttrValueServiceImpl.java new file mode 100644 index 0000000..956fbbf --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/ProductAttrValueServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.ProductAttrValueDao; +import com.bookstore.bookmall.product.entity.ProductAttrValueEntity; +import com.bookstore.bookmall.product.service.ProductAttrValueService; + + +@Service("productAttrValueService") +public class ProductAttrValueServiceImpl extends ServiceImpl implements ProductAttrValueService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuImagesServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuImagesServiceImpl.java new file mode 100644 index 0000000..c6efbd4 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuImagesServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.SkuImagesDao; +import com.bookstore.bookmall.product.entity.SkuImagesEntity; +import com.bookstore.bookmall.product.service.SkuImagesService; + + +@Service("skuImagesService") +public class SkuImagesServiceImpl extends ServiceImpl implements SkuImagesService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuInfoServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuInfoServiceImpl.java new file mode 100644 index 0000000..42d0d5c --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuInfoServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.SkuInfoDao; +import com.bookstore.bookmall.product.entity.SkuInfoEntity; +import com.bookstore.bookmall.product.service.SkuInfoService; + + +@Service("skuInfoService") +public class SkuInfoServiceImpl extends ServiceImpl implements SkuInfoService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuSaleAttrValueServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuSaleAttrValueServiceImpl.java new file mode 100644 index 0000000..7a9d74c --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SkuSaleAttrValueServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.SkuSaleAttrValueDao; +import com.bookstore.bookmall.product.entity.SkuSaleAttrValueEntity; +import com.bookstore.bookmall.product.service.SkuSaleAttrValueService; + + +@Service("skuSaleAttrValueService") +public class SkuSaleAttrValueServiceImpl extends ServiceImpl implements SkuSaleAttrValueService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuCommentServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuCommentServiceImpl.java new file mode 100644 index 0000000..d93b326 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuCommentServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.SpuCommentDao; +import com.bookstore.bookmall.product.entity.SpuCommentEntity; +import com.bookstore.bookmall.product.service.SpuCommentService; + + +@Service("spuCommentService") +public class SpuCommentServiceImpl extends ServiceImpl implements SpuCommentService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuImagesServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuImagesServiceImpl.java new file mode 100644 index 0000000..50dddab --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuImagesServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.SpuImagesDao; +import com.bookstore.bookmall.product.entity.SpuImagesEntity; +import com.bookstore.bookmall.product.service.SpuImagesService; + + +@Service("spuImagesService") +public class SpuImagesServiceImpl extends ServiceImpl implements SpuImagesService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoDescServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoDescServiceImpl.java new file mode 100644 index 0000000..5b1560e --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoDescServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.SpuInfoDescDao; +import com.bookstore.bookmall.product.entity.SpuInfoDescEntity; +import com.bookstore.bookmall.product.service.SpuInfoDescService; + + +@Service("spuInfoDescService") +public class SpuInfoDescServiceImpl extends ServiceImpl implements SpuInfoDescService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoServiceImpl.java b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoServiceImpl.java new file mode 100644 index 0000000..de0d628 --- /dev/null +++ b/book-product/src/main/java/com/bookstore/bookmall/product/service/impl/SpuInfoServiceImpl.java @@ -0,0 +1,29 @@ +package com.bookstore.bookmall.product.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bookstore.common.utils.PageUtils; +import com.bookstore.common.utils.Query; + +import com.bookstore.bookmall.product.dao.SpuInfoDao; +import com.bookstore.bookmall.product.entity.SpuInfoEntity; +import com.bookstore.bookmall.product.service.SpuInfoService; + + +@Service("spuInfoService") +public class SpuInfoServiceImpl extends ServiceImpl implements SpuInfoService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + ); + + return new PageUtils(page); + } + +} \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/AttrAttrgroupRelationDao.xml b/book-product/src/main/resources/mapper/product/AttrAttrgroupRelationDao.xml new file mode 100644 index 0000000..e9e9443 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/AttrAttrgroupRelationDao.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/AttrDao.xml b/book-product/src/main/resources/mapper/product/AttrDao.xml new file mode 100644 index 0000000..2b86b96 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/AttrDao.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/AttrGroupDao.xml b/book-product/src/main/resources/mapper/product/AttrGroupDao.xml new file mode 100644 index 0000000..a31b9c2 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/AttrGroupDao.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/BrandDao.xml b/book-product/src/main/resources/mapper/product/BrandDao.xml new file mode 100644 index 0000000..80e98d2 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/BrandDao.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/CategoryBrandRelationDao.xml b/book-product/src/main/resources/mapper/product/CategoryBrandRelationDao.xml new file mode 100644 index 0000000..6d59003 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/CategoryBrandRelationDao.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/CategoryDao.xml b/book-product/src/main/resources/mapper/product/CategoryDao.xml new file mode 100644 index 0000000..70e0aa9 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/CategoryDao.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/CommentReplayDao.xml b/book-product/src/main/resources/mapper/product/CommentReplayDao.xml new file mode 100644 index 0000000..814ac4c --- /dev/null +++ b/book-product/src/main/resources/mapper/product/CommentReplayDao.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/ProductAttrValueDao.xml b/book-product/src/main/resources/mapper/product/ProductAttrValueDao.xml new file mode 100644 index 0000000..5c63e1d --- /dev/null +++ b/book-product/src/main/resources/mapper/product/ProductAttrValueDao.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/SkuImagesDao.xml b/book-product/src/main/resources/mapper/product/SkuImagesDao.xml new file mode 100644 index 0000000..83d8a61 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/SkuImagesDao.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/SkuInfoDao.xml b/book-product/src/main/resources/mapper/product/SkuInfoDao.xml new file mode 100644 index 0000000..1accb86 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/SkuInfoDao.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/SkuSaleAttrValueDao.xml b/book-product/src/main/resources/mapper/product/SkuSaleAttrValueDao.xml new file mode 100644 index 0000000..df20559 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/SkuSaleAttrValueDao.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/SpuCommentDao.xml b/book-product/src/main/resources/mapper/product/SpuCommentDao.xml new file mode 100644 index 0000000..a33e284 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/SpuCommentDao.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/SpuImagesDao.xml b/book-product/src/main/resources/mapper/product/SpuImagesDao.xml new file mode 100644 index 0000000..efb1f0d --- /dev/null +++ b/book-product/src/main/resources/mapper/product/SpuImagesDao.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/SpuInfoDao.xml b/book-product/src/main/resources/mapper/product/SpuInfoDao.xml new file mode 100644 index 0000000..a8c9509 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/SpuInfoDao.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/book-product/src/main/resources/mapper/product/SpuInfoDescDao.xml b/book-product/src/main/resources/mapper/product/SpuInfoDescDao.xml new file mode 100644 index 0000000..e659091 --- /dev/null +++ b/book-product/src/main/resources/mapper/product/SpuInfoDescDao.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/mall-common/mall-common.iml b/mall-common/mall-common.iml new file mode 100644 index 0000000..ddaeab8 --- /dev/null +++ b/mall-common/mall-common.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mall-common/pom.xml b/mall-common/pom.xml new file mode 100644 index 0000000..7bd59e0 --- /dev/null +++ b/mall-common/pom.xml @@ -0,0 +1,19 @@ + + + + bookmall + com.bookstore.bookmall + 0.0.1-SNAPSHOT + + 4.0.0 + + mall-common + + + 8 + 8 + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8367ec2..e0630ad 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,9 @@ book-ware book-coupon book-product + renren-fast + renren-generator + mall-common diff --git a/renren-fast/Dockerfile b/renren-fast/Dockerfile new file mode 100644 index 0000000..2f0c477 --- /dev/null +++ b/renren-fast/Dockerfile @@ -0,0 +1,7 @@ +FROM java:8 +EXPOSE 8080 + +VOLUME /tmp +ADD renren-fast.jar /app.jar +RUN bash -c 'touch /app.jar' +ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/renren-fast/LICENSE b/renren-fast/LICENSE new file mode 100644 index 0000000..0148aba --- /dev/null +++ b/renren-fast/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 2019 人人开源 + + 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/renren-fast/README.md b/renren-fast/README.md new file mode 100644 index 0000000..a27030e --- /dev/null +++ b/renren-fast/README.md @@ -0,0 +1,113 @@ +**项目说明** +- renren-fast是一个轻量级的,前后端分离的Java快速开发平台,能快速开发项目并交付【接私活利器】 +- 支持MySQL、Oracle、SQL Server、PostgreSQL等主流数据库 +- 演示环境:http://demo.open.renren.io/renren-security +- 前端Gitee地址:https://gitee.com/renrenio/renren-fast-vue +- 前端GitCode地址:https://gitcode.com/renrenio/renren-fast-vue + +
+ + +**具有如下特点** +- 友好的代码结构及注释,便于阅读及二次开发 +- 实现前后端分离,通过token进行数据交互,前端再也不用关注后端技术 +- 灵活的权限控制,可控制到页面或按钮,满足绝大部分的权限需求 +- 页面交互使用Vue2.x,极大的提高了开发效率 +- 完善的代码生成机制,可在线生成entity、xml、dao、service、vue、sql代码,减少70%以上的开发任务 +- 引入quartz定时任务,可动态完成任务的添加、修改、删除、暂停、恢复及日志查看等功能 +- 引入API模板,根据token作为登录令牌,极大的方便了APP接口开发 +- 引入Hibernate Validator校验框架,轻松实现后端校验 +- 引入云存储服务,已支持:七牛云、阿里云、腾讯云等 +- 引入swagger文档支持,方便编写API接口文档 +
+ +**项目结构** +``` +renren-fast +├─db 项目SQL语句 +│ +├─common 公共模块 +│ ├─aspect 系统日志 +│ ├─exception 异常处理 +│ ├─validator 后台校验 +│ └─xss XSS过滤 +│ +├─config 配置信息 +│ +├─modules 功能模块 +│ ├─app API接口模块(APP调用) +│ ├─job 定时任务模块 +│ ├─oss 文件服务模块 +│ └─sys 权限模块 +│ +├─RenrenApplication 项目启动类 +│ +├──resources +│ ├─mapper SQL对应的XML文件 +│ └─static 静态资源 + +``` +
+ +**如何交流、反馈、参与贡献?** +- 开发文档:https://www.renren.io/guide +- Gitee仓库:https://gitee.com/renrenio/renren-fast +- GitCode仓库:https://gitcode.com/renrenio/renren-fast +- 人人开源:https://www.renren.io +- 官方QQ群:324780204、145799952 +- 技术讨论、二次开发等咨询、问题和建议,请移步到人人开源社区,我会在第一时间进行解答和回复! +- 如需关注项目最新动态,请Watch、Star项目,同时也是对项目最好的支持 +- 微信扫码并关注【人人开源】,获得项目最新动态及更新提醒 + +
+ +![输入图片说明](https://images.gitee.com/uploads/images/2019/0307/090140_260d672d_63154.jpeg "在这里输入图片标题") + +
+ + +**技术选型:** +- 核心框架:Spring Boot 2.1 +- 安全框架:Apache Shiro 1.4 +- 视图框架:Spring MVC 5.0 +- 持久层框架:MyBatis 3.3 +- 定时器:Quartz 2.3 +- 数据库连接池:Druid 1.0 +- 日志管理:SLF4J 1.7、Log4j +- 页面交互:Vue2.x +
+ + + **后端部署** +- 通过git下载源码 +- 创建数据库renren_fast,数据库编码为UTF-8 +- 执行db/mysql.sql文件,初始化数据 +- 修改application-dev.yml,更新MySQL账号和密码 +- IDEA运行RenrenApplication.java,则可启动项目 +- Swagger文档路径:http://localhost:8080/renren-fast/swagger/index.html +- Swagger注解路径:http://localhost:8080/renren-fast/swagger-ui.html + +
+ + **前端部署** + - 本项目是前后端分离的,还需要部署前端,才能运行起来 + - 前端Gitee地址:https://gitee.com/renrenio/renren-fast-vue + - 前端GitCode地址:https://gitcode.com/renrenio/renren-fast-vue + - 前端部署完毕,就可以访问项目了,账号:admin,密码:admin + +
+ + +**接口文档效果图:** +![输入图片说明](https://images.gitee.com/uploads/images/2018/0728/145341_73ba6f75_63154.jpeg "在这里输入图片标题") + +


+ + +**效果图:** +![输入图片说明](https://gitee.com/uploads/images/2018/0505/173115_d3c045ef_63154.jpeg "在这里输入图片标题") +![输入图片说明](https://gitee.com/uploads/images/2018/0624/225728_b06f72b3_63154.jpeg "在这里输入图片标题") +![输入图片说明](https://gitee.com/uploads/images/2018/0505/173140_79928d91_63154.jpeg "在这里输入图片标题") +![输入图片说明](https://gitee.com/uploads/images/2018/0505/173151_12d065db_63154.jpeg "在这里输入图片标题") + +
diff --git a/renren-fast/db/mysql.sql b/renren-fast/db/mysql.sql new file mode 100644 index 0000000..be1caef --- /dev/null +++ b/renren-fast/db/mysql.sql @@ -0,0 +1,356 @@ +-- 菜单 +CREATE TABLE `sys_menu` ( + `menu_id` bigint NOT NULL AUTO_INCREMENT, + `parent_id` bigint COMMENT '父菜单ID,一级菜单为0', + `name` varchar(50) COMMENT '菜单名称', + `url` varchar(200) COMMENT '菜单URL', + `perms` varchar(500) COMMENT '授权(多个用逗号分隔,如:user:list,user:create)', + `type` int COMMENT '类型 0:目录 1:菜单 2:按钮', + `icon` varchar(50) COMMENT '菜单图标', + `order_num` int COMMENT '排序', + PRIMARY KEY (`menu_id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='菜单管理'; + +-- 系统用户 +CREATE TABLE `sys_user` ( + `user_id` bigint NOT NULL AUTO_INCREMENT, + `username` varchar(50) NOT NULL COMMENT '用户名', + `password` varchar(100) COMMENT '密码', + `salt` varchar(20) COMMENT '盐', + `email` varchar(100) COMMENT '邮箱', + `mobile` varchar(100) COMMENT '手机号', + `status` tinyint COMMENT '状态 0:禁用 1:正常', + `create_user_id` bigint(20) COMMENT '创建者ID', + `create_time` datetime COMMENT '创建时间', + PRIMARY KEY (`user_id`), + UNIQUE INDEX (`username`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统用户'; + +-- 系统用户Token +CREATE TABLE `sys_user_token` ( + `user_id` bigint(20) NOT NULL, + `token` varchar(100) NOT NULL COMMENT 'token', + `expire_time` datetime DEFAULT NULL COMMENT '过期时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`user_id`), + UNIQUE KEY `token` (`token`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统用户Token'; + +-- 系统验证码 +CREATE TABLE `sys_captcha` ( + `uuid` char(36) NOT NULL COMMENT 'uuid', + `code` varchar(6) NOT NULL COMMENT '验证码', + `expire_time` datetime DEFAULT NULL COMMENT '过期时间', + PRIMARY KEY (`uuid`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统验证码'; + +-- 角色 +CREATE TABLE `sys_role` ( + `role_id` bigint NOT NULL AUTO_INCREMENT, + `role_name` varchar(100) COMMENT '角色名称', + `remark` varchar(100) COMMENT '备注', + `create_user_id` bigint(20) COMMENT '创建者ID', + `create_time` datetime COMMENT '创建时间', + PRIMARY KEY (`role_id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='角色'; + +-- 用户与角色对应关系 +CREATE TABLE `sys_user_role` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `user_id` bigint COMMENT '用户ID', + `role_id` bigint COMMENT '角色ID', + PRIMARY KEY (`id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='用户与角色对应关系'; + +-- 角色与菜单对应关系 +CREATE TABLE `sys_role_menu` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `role_id` bigint COMMENT '角色ID', + `menu_id` bigint COMMENT '菜单ID', + PRIMARY KEY (`id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='角色与菜单对应关系'; + +-- 系统配置信息 +CREATE TABLE `sys_config` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `param_key` varchar(50) COMMENT 'key', + `param_value` varchar(2000) COMMENT 'value', + `status` tinyint DEFAULT 1 COMMENT '状态 0:隐藏 1:显示', + `remark` varchar(500) COMMENT '备注', + PRIMARY KEY (`id`), + UNIQUE INDEX (`param_key`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统配置信息表'; + + +-- 系统日志 +CREATE TABLE `sys_log` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `username` varchar(50) COMMENT '用户名', + `operation` varchar(50) COMMENT '用户操作', + `method` varchar(200) COMMENT '请求方法', + `params` varchar(5000) COMMENT '请求参数', + `time` bigint NOT NULL COMMENT '执行时长(毫秒)', + `ip` varchar(64) COMMENT 'IP地址', + `create_date` datetime COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='系统日志'; + + +-- 文件上传 +CREATE TABLE `sys_oss` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `url` varchar(200) COMMENT 'URL地址', + `create_date` datetime COMMENT '创建时间', + PRIMARY KEY (`id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='文件上传'; + + +-- 定时任务 +CREATE TABLE `schedule_job` ( + `job_id` bigint(20) NOT NULL AUTO_INCREMENT 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(4) DEFAULT NULL COMMENT '任务状态 0:正常 1:暂停', + `remark` varchar(255) DEFAULT NULL COMMENT '备注', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`job_id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='定时任务'; + +-- 定时任务日志 +CREATE TABLE `schedule_job_log` ( + `log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务日志id', + `job_id` bigint(20) NOT NULL COMMENT '任务id', + `bean_name` varchar(200) DEFAULT NULL COMMENT 'spring bean名称', + `params` varchar(2000) DEFAULT NULL COMMENT '参数', + `status` tinyint(4) NOT NULL COMMENT '任务状态 0:成功 1:失败', + `error` varchar(2000) DEFAULT NULL COMMENT '失败信息', + `times` int(11) NOT NULL COMMENT '耗时(单位:毫秒)', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`log_id`), + KEY `job_id` (`job_id`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='定时任务日志'; + + + +-- 用户表 +CREATE TABLE `tb_user` ( + `user_id` bigint NOT NULL AUTO_INCREMENT, + `username` varchar(50) NOT NULL COMMENT '用户名', + `mobile` varchar(20) NOT NULL COMMENT '手机号', + `password` varchar(64) COMMENT '密码', + `create_time` datetime COMMENT '创建时间', + PRIMARY KEY (`user_id`), + UNIQUE INDEX (`username`) +) ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='用户'; + + + + + + +-- 初始数据 +INSERT INTO `sys_user` (`user_id`, `username`, `password`, `salt`, `email`, `mobile`, `status`, `create_user_id`, `create_time`) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', '2016-11-11 11:11:11'); + +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7); +INSERT INTO `sys_menu`(`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6); + +INSERT INTO `sys_config` (`param_key`, `param_value`, `status`, `remark`) VALUES ('CLOUD_STORAGE_CONFIG_KEY', '{\"aliyunAccessKeyId\":\"\",\"aliyunAccessKeySecret\":\"\",\"aliyunBucketName\":\"\",\"aliyunDomain\":\"\",\"aliyunEndPoint\":\"\",\"aliyunPrefix\":\"\",\"qcloudBucketName\":\"\",\"qcloudDomain\":\"\",\"qcloudPrefix\":\"\",\"qcloudSecretId\":\"\",\"qcloudSecretKey\":\"\",\"qiniuAccessKey\":\"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ\",\"qiniuBucketName\":\"ios-app\",\"qiniuDomain\":\"http://7xqbwh.dl1.z0.glb.clouddn.com\",\"qiniuPrefix\":\"upload\",\"qiniuSecretKey\":\"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV\",\"type\":1}', '0', '云存储配置信息'); +INSERT INTO `schedule_job` (`bean_name`, `params`, `cron_expression`, `status`, `remark`, `create_time`) VALUES ('testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', now()); + + +-- 账号:13612345678 密码:admin +INSERT INTO `tb_user` (`username`, `mobile`, `password`, `create_time`) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41'); + + + + + + + + +-- 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); diff --git a/renren-fast/db/oracle.sql b/renren-fast/db/oracle.sql new file mode 100644 index 0000000..56c23e5 --- /dev/null +++ b/renren-fast/db/oracle.sql @@ -0,0 +1,346 @@ +-- 菜单 +CREATE TABLE sys_menu ( + menu_id NUMBER(20, 0) NOT NULL, + parent_id NUMBER(20, 0) NOT NULL, + name varchar2(50), + url varchar2(200), + perms varchar2(500), + type NUMBER(2, 0), + icon varchar2(50), + order_num NUMBER(8, 0), + PRIMARY KEY (menu_id) +); + +-- 系统用户 +CREATE TABLE sys_user ( + user_id NUMBER(20, 0) NOT NULL, + username varchar2(50) NOT NULL, + password varchar2(100), + salt varchar2(20), + email varchar2(100), + mobile varchar2(100), + status NUMBER(2, 0) NOT NULL, + create_user_id NUMBER(20, 0) NOT NULL, + create_time timestamp, + PRIMARY KEY (user_id) +); +CREATE UNIQUE INDEX index_sys_user_username on sys_user(username); + +-- 系统用户Token +CREATE TABLE sys_user_token ( + user_id NUMBER(20, 0) NOT NULL, + token varchar2(100) NOT NULL, + expire_time timestamp, + update_time timestamp, + PRIMARY KEY (user_id) +); +CREATE UNIQUE INDEX index_token on sys_user_token(token); + +-- 系统验证码 +CREATE TABLE sys_captcha ( + uuid varchar2(36) NOT NULL, + code varchar2(6) NOT NULL, + expire_time timestamp, + PRIMARY KEY (uuid) +); + +-- 角色 +CREATE TABLE sys_role ( + role_id NUMBER(20, 0) NOT NULL, + role_name varchar2(100), + remark varchar2(100), + create_user_id NUMBER(20, 0) NOT NULL, + create_time timestamp, + PRIMARY KEY (role_id) +); + +-- 用户与角色对应关系 +CREATE TABLE sys_user_role ( + id NUMBER(20, 0) NOT NULL, + user_id NUMBER(20, 0) NOT NULL, + role_id NUMBER(20, 0) NOT NULL, + PRIMARY KEY (id) +); + +-- 角色与菜单对应关系 +CREATE TABLE sys_role_menu ( + id NUMBER(20, 0) NOT NULL, + role_id NUMBER(20, 0) NOT NULL, + menu_id NUMBER(20, 0) NOT NULL, + PRIMARY KEY (id) +); + +-- 系统配置信息 +CREATE TABLE sys_config ( + id NUMBER(20, 0) NOT NULL, + param_key varchar2(50), + param_value varchar2(4000), + status NUMBER(2, 0) DEFAULT 1 NOT NULL, + remark varchar2(500), + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX index_param_key on sys_config(param_key); + + +-- 系统日志 +CREATE TABLE sys_log ( + id NUMBER(20, 0) NOT NULL, + username varchar2(50), + operation varchar2(50), + method varchar2(200), + params clob, + time NUMBER(20, 0) NOT NULL, + ip varchar2(64), + create_date timestamp, + PRIMARY KEY (id) +); + +-- 文件上传 +CREATE TABLE sys_oss ( + id NUMBER(20, 0) NOT NULL, + url varchar2(200), + create_date timestamp, + PRIMARY KEY (id) +); + +-- 定时任务 +CREATE TABLE schedule_job ( + job_id NUMBER(20, 0) NOT NULL, + bean_name varchar2(200), + params varchar2(2000), + cron_expression varchar2(100), + status NUMBER(2, 0) NOT NULL, + remark varchar2(255), + create_time timestamp, + PRIMARY KEY (job_id) +); + +-- 定时任务日志 +CREATE TABLE schedule_job_log ( + 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) NOT NULL, + error varchar2(2000), + times NUMBER(10, 0) NOT NULL, + create_time timestamp, + PRIMARY KEY (log_id) +); +CREATE INDEX index_job_id on schedule_job_log(job_id); + +-- 用户表 +CREATE TABLE tb_user ( + user_id NUMBER(20, 0) NOT NULL, + username varchar2(50) NOT NULL, + mobile varchar2(20) NOT NULL, + password varchar2(64), + create_time timestamp, + PRIMARY KEY (user_id) +); +CREATE UNIQUE INDEX index_tb_user_username on tb_user(username); + +INSERT INTO sys_user (user_id, username, password, salt, email, mobile, status, create_user_id, create_time) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', CURRENT_DATE); + +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6); + + + +INSERT INTO sys_config (id, param_key, param_value, status, remark) VALUES (1, 'CLOUD_STORAGE_CONFIG_KEY', '{"aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","aliyunDomain":"","aliyunEndPoint":"","aliyunPrefix":"","qcloudBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuBucketName":"ios-app","qiniuDomain":"http://7xlij2.com1.z0.glb.clouddn.com","qiniuPrefix":"upload","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","type":1}', '0', '云存储配置信息'); + +INSERT INTO schedule_job (job_id, bean_name, params, cron_expression, status, remark, create_time) VALUES (1, 'testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', CURRENT_DATE); + + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (user_id, username, mobile, password, create_time) VALUES (1, 'mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', 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-fast/db/postgresql.sql b/renren-fast/db/postgresql.sql new file mode 100644 index 0000000..923da2c --- /dev/null +++ b/renren-fast/db/postgresql.sql @@ -0,0 +1,364 @@ +-- 菜单 +CREATE TABLE sys_menu ( + menu_id bigserial, + parent_id int8, + name varchar(50), + url varchar(200), + perms varchar(500), + type int, + icon varchar(50), + order_num int, + PRIMARY KEY (menu_id) +); + + +-- 系统用户 +CREATE TABLE sys_user ( + user_id bigserial, + username varchar(50) NOT NULL, + password varchar(100), + salt varchar(20), + email varchar(100), + mobile varchar(100), + status int, + create_user_id int8, + create_time timestamp, + PRIMARY KEY (user_id), + UNIQUE (username) +); + + +-- 系统用户Token +CREATE TABLE sys_user_token ( + user_id bigserial, + token varchar(100) NOT NULL, + expire_time timestamp, + update_time timestamp, + PRIMARY KEY (user_id), + UNIQUE (token) +); + +-- 系统验证码 +CREATE TABLE sys_captcha ( + uuid varchar(36) NOT NULL, + code varchar(6) NOT NULL, + expire_time timestamp, + PRIMARY KEY (uuid) +); + +-- 角色 +CREATE TABLE sys_role ( + role_id bigserial, + role_name varchar(100), + remark varchar(100), + create_user_id int8, + create_time timestamp, + PRIMARY KEY (role_id) +); + +-- 用户与角色对应关系 +CREATE TABLE sys_user_role ( + id bigserial, + user_id int8, + role_id int8, + PRIMARY KEY (id) +); + +-- 角色与菜单对应关系 +CREATE TABLE sys_role_menu ( + id bigserial, + role_id int8, + menu_id int8, + PRIMARY KEY (id) +); + +-- 系统配置信息 +CREATE TABLE sys_config ( + id bigserial, + param_key varchar(50), + param_value varchar(2000), + status int DEFAULT 1, + remark varchar(500), + PRIMARY KEY (id), + UNIQUE (param_key) +); + + +-- 系统日志 +CREATE TABLE sys_log ( + id bigserial, + username varchar(50), + operation varchar(50), + method varchar(200), + params varchar(5000), + time int8 NOT NULL, + ip varchar(64), + create_date timestamp, + PRIMARY KEY (id) +); + +-- 文件上传 +CREATE TABLE sys_oss ( + id bigserial, + url varchar(200), + create_date timestamp, + PRIMARY KEY (id) +); + + +-- 定时任务 +CREATE TABLE schedule_job ( + job_id bigserial, + bean_name varchar(200), + params varchar(2000), + cron_expression varchar(100), + status int, + remark varchar(255), + create_time timestamp, + PRIMARY KEY (job_id) +); + +-- 定时任务日志 +CREATE TABLE schedule_job_log ( + log_id bigserial, + job_id int8 NOT NULL, + bean_name varchar(200), + params varchar(2000), + status int NOT NULL, + error varchar(2000), + times int NOT NULL, + create_time timestamp, + PRIMARY KEY (log_id) +); +CREATE INDEX index_job_id on schedule_job_log(job_id); + +-- 用户表 +CREATE TABLE tb_user ( + user_id bigserial, + username varchar(50) NOT NULL, + mobile varchar(20) NOT NULL, + password varchar(64), + create_time timestamp, + PRIMARY KEY (user_id), + UNIQUE (username) +); + + +INSERT INTO sys_user (user_id, username, password, salt, email, mobile, status, create_user_id, create_time) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', '2016-11-11 11:11:11'); + +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6); + + +INSERT INTO sys_config (param_key, param_value, status, remark) VALUES ('CLOUD_STORAGE_CONFIG_KEY', '{"aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","aliyunDomain":"","aliyunEndPoint":"","aliyunPrefix":"","qcloudBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuBucketName":"ios-app","qiniuDomain":"http://7xlij2.com1.z0.glb.clouddn.com","qiniuPrefix":"upload","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","type":1}', '0', '云存储配置信息'); + +INSERT INTO schedule_job (bean_name, params, cron_expression, status, remark, create_time) VALUES ('testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', '2016-12-01 23:16:46'); + + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (username, mobile, password, create_time) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41'); + + +alter sequence sys_menu_menu_id_seq restart with 31; +alter sequence sys_user_user_id_seq restart with 2; + + +-- 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-fast/db/sqlserver.sql b/renren-fast/db/sqlserver.sql new file mode 100644 index 0000000..de38fa8 --- /dev/null +++ b/renren-fast/db/sqlserver.sql @@ -0,0 +1,512 @@ +-- 菜单 +CREATE TABLE sys_menu ( + menu_id bigint NOT NULL IDENTITY(1,1), + parent_id bigint, + name varchar(50), + url varchar(200), + perms varchar(500), + type int, + icon varchar(50), + order_num int, + PRIMARY KEY (menu_id) +); + +-- 系统用户 +CREATE TABLE sys_user ( + user_id bigint NOT NULL IDENTITY(1,1), + username varchar(50) NOT NULL, + password varchar(100), + salt varchar(20), + email varchar(100), + mobile varchar(100), + status tinyint, + create_user_id bigint, + create_time datetime, + PRIMARY KEY (user_id), + UNIQUE (username) +); + +-- 系统用户Token +CREATE TABLE sys_user_token ( + user_id bigint NOT NULL, + token varchar(100) NOT NULL, + expire_time datetime, + update_time datetime, + PRIMARY KEY (user_id), + UNIQUE (token) +); + +-- 系统验证码 +CREATE TABLE sys_captcha ( + uuid varchar(36) NOT NULL, + code varchar(6) NOT NULL, + expire_time datetime, + PRIMARY KEY (uuid) +); + +-- 角色 +CREATE TABLE sys_role ( + role_id bigint NOT NULL IDENTITY(1,1), + role_name varchar(100), + remark varchar(100), + create_user_id bigint, + create_time datetime, +PRIMARY KEY (role_id) +); + +-- 用户与角色对应关系 +CREATE TABLE sys_user_role ( + id bigint NOT NULL IDENTITY(1,1), + user_id bigint, + role_id bigint, +PRIMARY KEY (id) +); + +-- 角色与菜单对应关系 +CREATE TABLE sys_role_menu ( + id bigint NOT NULL IDENTITY(1,1), + role_id bigint, + menu_id bigint, +PRIMARY KEY (id) +); + +-- 系统配置信息 +CREATE TABLE sys_config ( + id bigint NOT NULL IDENTITY(1,1), + param_key varchar(50), + param_value varchar(2000), + status tinyint DEFAULT 1, + remark varchar(500), + PRIMARY KEY (id), + UNIQUE (param_key) +); + +-- 系统日志 +CREATE TABLE sys_log ( + id bigint NOT NULL IDENTITY(1,1), + username varchar(50), + operation varchar(50), + method varchar(200), + params varchar(5000), + time bigint NOT NULL, + ip varchar(64), + create_date datetime, +PRIMARY KEY (id) +); + +-- 文件上传 +CREATE TABLE sys_oss ( + id bigint NOT NULL IDENTITY(1,1), + url varchar(200), + create_date datetime, + PRIMARY KEY (id) +); + +-- 定时任务 +CREATE TABLE schedule_job ( + job_id bigint NOT NULL IDENTITY(1,1), + bean_name varchar(200), + params varchar(2000), + cron_expression varchar(100), + status tinyint, + remark varchar(255), + create_time datetime, + PRIMARY KEY (job_id) +); + +-- 定时任务日志 +CREATE TABLE schedule_job_log ( + log_id bigint NOT NULL IDENTITY(1,1), + job_id bigint NOT NULL, + bean_name varchar(200), + params varchar(2000), + status tinyint NOT NULL, + error varchar(2000), + times int NOT NULL, + create_time datetime, + PRIMARY KEY (log_id), + INDEX job_id (job_id) +); + +-- 用户表 +CREATE TABLE tb_user ( + user_id bigint NOT NULL IDENTITY(1,1), + username varchar(50) NOT NULL, + mobile varchar(20) NOT NULL, + password varchar(64), + create_time datetime, + PRIMARY KEY (user_id), + UNIQUE (username) +); + +SET IDENTITY_INSERT sys_user ON; +INSERT INTO sys_user (user_id, username, password, salt, email, mobile, status, create_user_id, create_time) VALUES ('1', 'admin', '9ec9750e709431dad22365cabc5c625482e574c74adaebba7dd02f1129e4ce1d', 'YzcmCZNvbXocrsz9dm8e', 'root@renren.io', '13612345678', '1', '1', '2016-11-11 11:11:11'); +SET IDENTITY_INSERT sys_user OFF; + +SET IDENTITY_INSERT sys_menu ON; +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (1, 0, '系统管理', NULL, NULL, 0, 'system', 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (2, 1, '管理员列表', 'sys/user', NULL, 1, 'admin', 1); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (3, 1, '角色管理', 'sys/role', NULL, 1, 'role', 2); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (4, 1, '菜单管理', 'sys/menu', NULL, 1, 'menu', 3); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (5, 1, 'SQL监控', 'http://localhost:8080/renren-fast/druid/sql.html', NULL, 1, 'sql', 4); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (6, 1, '定时任务', 'job/schedule', NULL, 1, 'job', 5); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (7, 6, '查看', NULL, 'sys:schedule:list,sys:schedule:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (8, 6, '新增', NULL, 'sys:schedule:save', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (9, 6, '修改', NULL, 'sys:schedule:update', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (10, 6, '删除', NULL, 'sys:schedule:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (11, 6, '暂停', NULL, 'sys:schedule:pause', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (12, 6, '恢复', NULL, 'sys:schedule:resume', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (13, 6, '立即执行', NULL, 'sys:schedule:run', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (14, 6, '日志列表', NULL, 'sys:schedule:log', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (15, 2, '查看', NULL, 'sys:user:list,sys:user:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (16, 2, '新增', NULL, 'sys:user:save,sys:role:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (17, 2, '修改', NULL, 'sys:user:update,sys:role:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (18, 2, '删除', NULL, 'sys:user:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (19, 3, '查看', NULL, 'sys:role:list,sys:role:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (20, 3, '新增', NULL, 'sys:role:save,sys:menu:list', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (21, 3, '修改', NULL, 'sys:role:update,sys:menu:list', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (22, 3, '删除', NULL, 'sys:role:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (23, 4, '查看', NULL, 'sys:menu:list,sys:menu:info', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (24, 4, '新增', NULL, 'sys:menu:save,sys:menu:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (25, 4, '修改', NULL, 'sys:menu:update,sys:menu:select', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (26, 4, '删除', NULL, 'sys:menu:delete', 2, NULL, 0); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (27, 1, '参数管理', 'sys/config', 'sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete', 1, 'config', 6); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (29, 1, '系统日志', 'sys/log', 'sys:log:list', 1, 'log', 7); +INSERT INTO sys_menu(menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (30, 1, '文件上传', 'oss/oss', 'sys:oss:all', 1, 'oss', 6); + +SET IDENTITY_INSERT sys_menu OFF; + + +INSERT INTO sys_config (param_key, param_value, status, remark) VALUES ('CLOUD_STORAGE_CONFIG_KEY', '{"aliyunAccessKeyId":"","aliyunAccessKeySecret":"","aliyunBucketName":"","aliyunDomain":"","aliyunEndPoint":"","aliyunPrefix":"","qcloudBucketName":"","qcloudDomain":"","qcloudPrefix":"","qcloudSecretId":"","qcloudSecretKey":"","qiniuAccessKey":"NrgMfABZxWLo5B-YYSjoE8-AZ1EISdi1Z3ubLOeZ","qiniuBucketName":"ios-app","qiniuDomain":"http://7xlij2.com1.z0.glb.clouddn.com","qiniuPrefix":"upload","qiniuSecretKey":"uIwJHevMRWU0VLxFvgy0tAcOdGqasdtVlJkdy6vV","type":1}', '0', '云存储配置信息'); + +INSERT INTO schedule_job (bean_name, params, cron_expression, status, remark, create_time) VALUES ('testTask', 'renren', '0 0/30 * * * ?', '0', '参数测试', '2016-12-01 23:16:46'); + + +-- 账号:13612345678 密码:admin +INSERT INTO tb_user (username, mobile, password, create_time) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41'); + + + + + +-- 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 + diff --git a/renren-fast/docker-compose.yml b/renren-fast/docker-compose.yml new file mode 100644 index 0000000..432ba38 --- /dev/null +++ b/renren-fast/docker-compose.yml @@ -0,0 +1,8 @@ +version: '2' +services: + renren-fast: + image: renren/fast + ports: + - "8080:8080" + environment: + - spring.profiles.active=dev \ No newline at end of file diff --git a/renren-fast/pom.xml b/renren-fast/pom.xml new file mode 100644 index 0000000..13c6cdd --- /dev/null +++ b/renren-fast/pom.xml @@ -0,0 +1,335 @@ + + + 4.0.0 + io.renren + renren-fast + 3.0.0 + jar + renren-fast + + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + + + UTF-8 + UTF-8 + 1.8 + 3.3.1 + 8.0.28 + 4.0 + 11.2.0.3 + 1.1.13 + 2.3.0 + 2.6 + 1.2.2 + 2.5 + 1.10 + 1.10 + 1.9.0 + 0.7.0 + 0.0.9 + 7.2.23 + 2.8.3 + 4.4 + 2.7.0 + 2.9.9 + 2.8.5 + 1.2.79 + 4.1.1 + 1.18.4 + + + /work/renren + ${project.artifactId}-${project.version}.jar + 192.168.1.10:22 + root + 123456 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework + spring-context-support + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatisplus.version} + + + com.baomidou + mybatis-plus-generator + + + + + mysql + mysql-connector-java + ${mysql.version} + + + + com.oracle + ojdbc6 + ${oracle.version} + + + + com.microsoft.sqlserver + sqljdbc4 + ${mssql.version} + + + + org.postgresql + postgresql + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + org.quartz-scheduler + quartz + ${quartz.version} + + + com.mchange + c3p0 + + + + + commons-lang + commons-lang + ${commons.lang.version} + + + commons-fileupload + commons-fileupload + ${commons.fileupload.version} + + + commons-io + commons-io + ${commons.io.version} + + + commons-codec + commons-codec + ${commons.codec.version} + + + commons-configuration + commons-configuration + ${commons.configuration.version} + + + org.apache.shiro + shiro-core + ${shiro.version} + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + com.github.axet + kaptcha + ${kaptcha.version} + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + com.qiniu + qiniu-java-sdk + ${qiniu.version} + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun.oss.version} + + + com.qcloud + cos_api + ${qcloud.cos.version} + + + org.slf4j + slf4j-log4j12 + + + + + joda-time + joda-time + ${joda.time.version} + + + com.google.code.gson + gson + ${gson.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + cn.hutool + hutool-all + ${hutool.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + + ${project.artifactId} + + + org.apache.maven.wagon + wagon-ssh + 2.8 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + org.codehaus.mojo + wagon-maven-plugin + 1.0 + + target/${pack-name} + + + + kill -9 `ps -ef |grep ${project.artifactId}.jar|grep -v "grep" |awk '{print $2}'` + + ${service-path}/renren.log 2>&1 & ]]> + + + + + true + + + + + com.spotify + docker-maven-plugin + 0.4.14 + + + + + + + + + + renren/fast + ${project.basedir} + + + / + ${project.build.directory} + ${project.build.finalName}.jar + + + + + + + + + + + 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-fast/src/main/java/io/renren/RenrenApplication.java b/renren-fast/src/main/java/io/renren/RenrenApplication.java new file mode 100644 index 0000000..915d6cb --- /dev/null +++ b/renren-fast/src/main/java/io/renren/RenrenApplication.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +@SpringBootApplication +public class RenrenApplication { + + public static void main(String[] args) { + SpringApplication.run(RenrenApplication.class, args); + } + +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/common/annotation/SysLog.java b/renren-fast/src/main/java/io/renren/common/annotation/SysLog.java new file mode 100644 index 0000000..4653480 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/annotation/SysLog.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.annotation; + +import java.lang.annotation.Documented; +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.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SysLog { + + String value() default ""; +} diff --git a/renren-fast/src/main/java/io/renren/common/aspect/RedisAspect.java b/renren-fast/src/main/java/io/renren/common/aspect/RedisAspect.java new file mode 100644 index 0000000..bb2a8e5 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/aspect/RedisAspect.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.aspect; + +import io.renren.common.exception.RRException; +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.context.annotation.Configuration; + +/** + * Redis切面处理类 + * + * @author Mark sunlightcs@gmail.com + */ +@Aspect +@Configuration +public class RedisAspect { + private Logger logger = LoggerFactory.getLogger(getClass()); + //是否开启redis缓存 true开启 false关闭 + @Value("${spring.redis.open: false}") + private boolean open; + + @Around("execution(* io.renren.common.utils.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 RRException("Redis服务异常"); + } + } + return result; + } +} diff --git a/renren-fast/src/main/java/io/renren/common/aspect/SysLogAspect.java b/renren-fast/src/main/java/io/renren/common/aspect/SysLogAspect.java new file mode 100644 index 0000000..ae047df --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/aspect/SysLogAspect.java @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.aspect; + +import com.google.gson.Gson; +import io.renren.common.annotation.SysLog; +import io.renren.common.utils.HttpContextUtils; +import io.renren.common.utils.IPUtils; +import io.renren.modules.sys.entity.SysLogEntity; +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.service.SysLogService; +import org.apache.shiro.SecurityUtils; +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.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.Date; + + +/** + * 系统日志,切面处理类 + * + * @author Mark sunlightcs@gmail.com + */ +@Aspect +@Component +public class SysLogAspect { + @Autowired + private SysLogService sysLogService; + + @Pointcut("@annotation(io.renren.common.annotation.SysLog)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + //执行方法 + Object result = point.proceed(); + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + + //保存日志 + saveSysLog(point, time); + + return result; + } + + private void saveSysLog(ProceedingJoinPoint joinPoint, long time) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + SysLogEntity sysLog = new SysLogEntity(); + SysLog syslog = method.getAnnotation(SysLog.class); + if(syslog != null){ + //注解上的描述 + sysLog.setOperation(syslog.value()); + } + + //请求的方法名 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = signature.getName(); + sysLog.setMethod(className + "." + methodName + "()"); + + //请求的参数 + Object[] args = joinPoint.getArgs(); + try{ + String params = new Gson().toJson(args); + sysLog.setParams(params); + }catch (Exception e){ + + } + + //获取request + HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); + //设置IP地址 + sysLog.setIp(IPUtils.getIpAddr(request)); + + //用户名 + String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername(); + sysLog.setUsername(username); + + sysLog.setTime(time); + sysLog.setCreateDate(new Date()); + //保存系统日志 + sysLogService.save(sysLog); + } +} diff --git a/renren-fast/src/main/java/io/renren/common/exception/RRException.java b/renren-fast/src/main/java/io/renren/common/exception/RRException.java new file mode 100644 index 0000000..5c27351 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/exception/RRException.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.exception; + +/** + * 自定义异常 + * + * @author Mark sunlightcs@gmail.com + */ +public class RRException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private String msg; + private int code = 500; + + public RRException(String msg) { + super(msg); + this.msg = msg; + } + + public RRException(String msg, Throwable e) { + super(msg, e); + this.msg = msg; + } + + public RRException(String msg, int code) { + super(msg); + this.msg = msg; + this.code = code; + } + + public RRException(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-fast/src/main/java/io/renren/common/exception/RRExceptionHandler.java b/renren-fast/src/main/java/io/renren/common/exception/RRExceptionHandler.java new file mode 100644 index 0000000..eb060a6 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/exception/RRExceptionHandler.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.exception; + +import io.renren.common.utils.R; +import org.apache.shiro.authz.AuthorizationException; +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; +import org.springframework.web.servlet.NoHandlerFoundException; + +/** + * 异常处理器 + * + * @author Mark sunlightcs@gmail.com + */ +@RestControllerAdvice +public class RRExceptionHandler { + private Logger logger = LoggerFactory.getLogger(getClass()); + + /** + * 处理自定义异常 + */ + @ExceptionHandler(RRException.class) + public R handleRRException(RRException e){ + R r = new R(); + r.put("code", e.getCode()); + r.put("msg", e.getMessage()); + + return r; + } + + @ExceptionHandler(NoHandlerFoundException.class) + public R handlerNoFoundException(Exception e) { + logger.error(e.getMessage(), e); + return R.error(404, "路径不存在,请检查路径是否正确"); + } + + @ExceptionHandler(DuplicateKeyException.class) + public R handleDuplicateKeyException(DuplicateKeyException e){ + logger.error(e.getMessage(), e); + return R.error("数据库中已存在该记录"); + } + + @ExceptionHandler(AuthorizationException.class) + public R handleAuthorizationException(AuthorizationException e){ + logger.error(e.getMessage(), e); + return R.error("没有权限,请联系管理员授权"); + } + + @ExceptionHandler(Exception.class) + public R handleException(Exception e){ + logger.error(e.getMessage(), e); + return R.error(); + } +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/BeanFindUtils.java b/renren-fast/src/main/java/io/renren/common/utils/BeanFindUtils.java new file mode 100644 index 0000000..d29f61c --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/BeanFindUtils.java @@ -0,0 +1,65 @@ +package io.renren.common.utils; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.core.type.filter.AssignableTypeFilter; + +import java.lang.annotation.Annotation; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 查询特定的类,该工具下的方法应该在程序启动完成之后才可以使用 + */ +public class BeanFindUtils { + + private static ClassPathScanningCandidateComponentProvider scanner; + + /** + * 查询指定了特定注解的类 + * @param basePackage 类所存放的包名 + * @param annotation 特定的注解 + * @return 目标类 + */ + public static Set> findAnnotation(String basePackage, Class annotation) { + ClassPathScanningCandidateComponentProvider scanner = getInstance(); + scanner.addIncludeFilter(new AnnotationTypeFilter(annotation)); + return getClasses(basePackage, scanner); + } + + /** + * 查询实现了特定接口的类 + * @param basePackage 类所存放的包名 + * @param interfaceClass 特定的接口 + * @return 目标类 + */ + public static Set> findInterface(String basePackage, Class interfaceClass) { + ClassPathScanningCandidateComponentProvider scanner = getInstance(); + scanner.addIncludeFilter(new AssignableTypeFilter(interfaceClass)); + return getClasses(basePackage, scanner); + } + + + private static Set> getClasses(String basePackage, ClassPathScanningCandidateComponentProvider scanner) { + Set beanDefinitions = scanner.findCandidateComponents(basePackage); + return beanDefinitions.stream() + .map(BeanDefinition::getBeanClassName) + .map(className -> { + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toSet()); + } + + private static ClassPathScanningCandidateComponentProvider getInstance(){ + if (scanner == null){ + scanner = new ClassPathScanningCandidateComponentProvider(false); + } + return scanner; + } + +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/common/utils/ConfigConstant.java b/renren-fast/src/main/java/io/renren/common/utils/ConfigConstant.java new file mode 100644 index 0000000..32897da --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/ConfigConstant.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +/** + * 系统参数相关Key + * + * @author Mark sunlightcs@gmail.com + */ +public class ConfigConstant { + /** + * 云存储配置KEY + */ + public final static String CLOUD_STORAGE_CONFIG_KEY = "CLOUD_STORAGE_CONFIG_KEY"; +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/Constant.java b/renren-fast/src/main/java/io/renren/common/utils/Constant.java new file mode 100644 index 0000000..da3d5bc --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/Constant.java @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + *

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

+ * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import io.renren.common.validator.group.AliyunGroup; +import io.renren.common.validator.group.QcloudGroup; +import io.renren.common.validator.group.QiniuGroup; + +import java.util.Optional; +import java.util.stream.Stream; + +/** + * 常量 + * + * @author Mark sunlightcs@gmail.com + */ +public class Constant { + /** + * 超级管理员ID + */ + public static final int SUPER_ADMIN = 1; + /** + * 当前页码 + */ + public static final String PAGE = "page"; + /** + * 每页显示记录数 + */ + public static final String LIMIT = "limit"; + /** + * 排序字段 + */ + public static final String ORDER_FIELD = "sidx"; + /** + * 排序方式 + */ + public static final String ORDER = "order"; + /** + * 升序 + */ + public static final String ASC = "asc"; + + /** + * 菜单类型 + * + * @author chenshun + * @email sunlightcs@gmail.com + * @date 2016年11月15日 下午1:24:29 + */ + public enum MenuType { + /** + * 目录 + */ + CATALOG(0), + /** + * 菜单 + */ + MENU(1), + /** + * 按钮 + */ + BUTTON(2); + + private int value; + + MenuType(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + /** + * 定时任务状态 + * + * @author chenshun + * @email sunlightcs@gmail.com + * @date 2016年12月3日 上午12:07:22 + */ + public enum ScheduleStatus { + /** + * 正常 + */ + NORMAL(0), + /** + * 暂停 + */ + PAUSE(1); + + private int value; + + ScheduleStatus(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + /** + * 云服务商 + */ + public enum CloudService { + /** + * 七牛云 + */ + QINIU(1, QiniuGroup.class), + /** + * 阿里云 + */ + ALIYUN(2, AliyunGroup.class), + /** + * 腾讯云 + */ + QCLOUD(3, QcloudGroup.class); + + private int value; + + private Class validatorGroupClass; + + CloudService(int value, Class validatorGroupClass) { + this.value = value; + this.validatorGroupClass = validatorGroupClass; + } + + public int getValue() { + return value; + } + + public Class getValidatorGroupClass() { + return this.validatorGroupClass; + } + + public static CloudService getByValue(Integer value) { + Optional first = Stream.of(CloudService.values()).filter(cs -> value.equals(cs.value)).findFirst(); + if (!first.isPresent()) { + throw new IllegalArgumentException("非法的枚举值:" + value); + } + return first.get(); + } + } + +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/DateUtils.java b/renren-fast/src/main/java/io/renren/common/utils/DateUtils.java new file mode 100644 index 0000000..798f7ba --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/DateUtils.java @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.apache.commons.lang.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.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 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-fast/src/main/java/io/renren/common/utils/HttpContextUtils.java b/renren-fast/src/main/java/io/renren/common/utils/HttpContextUtils.java new file mode 100644 index 0000000..09aa2c7 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/HttpContextUtils.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; + +public class HttpContextUtils { + + public static HttpServletRequest getHttpServletRequest() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } + + 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("Origin"); + } +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/IPUtils.java b/renren-fast/src/main/java/io/renren/common/utils/IPUtils.java new file mode 100644 index 0000000..2f20be6 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/IPUtils.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import com.alibaba.druid.util.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 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); + } + +// //使用代理,则获取第一个IP地址 +// if(StringUtils.isEmpty(ip) && ip.length() > 15) { +// if(ip.indexOf(",") > 0) { +// ip = ip.substring(0, ip.indexOf(",")); +// } +// } + + return ip; + } + +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/MapUtils.java b/renren-fast/src/main/java/io/renren/common/utils/MapUtils.java new file mode 100644 index 0000000..95b6fb3 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/MapUtils.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import java.util.HashMap; + + +/** + * Map工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class MapUtils extends HashMap { + + @Override + public MapUtils put(String key, Object value) { + super.put(key, value); + return this; + } +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/PageUtils.java b/renren-fast/src/main/java/io/renren/common/utils/PageUtils.java new file mode 100644 index 0000000..360452d --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/PageUtils.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import com.baomidou.mybatisplus.core.metadata.IPage; + +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 PageUtils(IPage page) { + this.list = page.getRecords(); + this.totalCount = (int)page.getTotal(); + this.pageSize = (int)page.getSize(); + this.currPage = (int)page.getCurrent(); + this.totalPage = (int)page.getPages(); + } + + 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-fast/src/main/java/io/renren/common/utils/Query.java b/renren-fast/src/main/java/io/renren/common/utils/Query.java new file mode 100644 index 0000000..ff825a0 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/Query.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.renren.common.xss.SQLFilter; +import org.apache.commons.lang.StringUtils; + +import java.util.Map; + +/** + * 查询参数 + * + * @author Mark sunlightcs@gmail.com + */ +public class Query { + + public IPage getPage(Map params) { + return this.getPage(params, null, false); + } + + public 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); + + //排序字段 + //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险) + String orderField = SQLFilter.sqlInject((String)params.get(Constant.ORDER_FIELD)); + String order = (String)params.get(Constant.ORDER); + + + //前端字段排序 + if(StringUtils.isNotEmpty(orderField) && StringUtils.isNotEmpty(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; + } +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/R.java b/renren-fast/src/main/java/io/renren/common/utils/R.java new file mode 100644 index 0000000..1da0da6 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/R.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import org.apache.http.HttpStatus; + +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); + put("msg", "success"); + } + + public static R error() { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员"); + } + + public static R error(String msg) { + return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, 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(); + } + + public R put(String key, Object value) { + super.put(key, value); + return this; + } +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/RedisKeys.java b/renren-fast/src/main/java/io/renren/common/utils/RedisKeys.java new file mode 100644 index 0000000..d033b05 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/RedisKeys.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +/** + * Redis所有Keys + * + * @author Mark sunlightcs@gmail.com + */ +public class RedisKeys { + + public static String getSysConfigKey(String key){ + return "sys:config:" + key; + } +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/RedisUtils.java b/renren-fast/src/main/java/io/renren/common/utils/RedisUtils.java new file mode 100644 index 0000000..34bbb8f --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/RedisUtils.java @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import com.google.gson.Gson; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.*; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +/** + * Redis工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class RedisUtils { + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private ValueOperations valueOperations; + @Autowired + private HashOperations hashOperations; + @Autowired + private ListOperations listOperations; + @Autowired + private SetOperations setOperations; + @Autowired + private ZSetOperations zSetOperations; + /** 默认过期时长,单位:秒 */ + public final static long DEFAULT_EXPIRE = 60 * 60 * 24; + /** 不设置过期时长 */ + public final static long NOT_EXPIRE = -1; + private final static Gson gson = new Gson(); + + public void set(String key, Object value, long expire){ + valueOperations.set(key, toJson(value)); + if(expire != NOT_EXPIRE){ + redisTemplate.expire(key, expire, TimeUnit.SECONDS); + } + } + + public void set(String key, Object value){ + set(key, value, DEFAULT_EXPIRE); + } + + public T get(String key, Class clazz, long expire) { + String value = valueOperations.get(key); + if(expire != NOT_EXPIRE){ + redisTemplate.expire(key, expire, TimeUnit.SECONDS); + } + return value == null ? null : fromJson(value, clazz); + } + + public T get(String key, Class clazz) { + return get(key, clazz, NOT_EXPIRE); + } + + public String get(String key, long expire) { + String value = valueOperations.get(key); + if(expire != NOT_EXPIRE){ + redisTemplate.expire(key, expire, TimeUnit.SECONDS); + } + return value; + } + + public String get(String key) { + return get(key, NOT_EXPIRE); + } + + public void delete(String key) { + redisTemplate.delete(key); + } + + /** + * Object转成JSON数据 + */ + private String toJson(Object object){ + if(object instanceof Integer || object instanceof Long || object instanceof Float || + object instanceof Double || object instanceof Boolean || object instanceof String){ + return String.valueOf(object); + } + return gson.toJson(object); + } + + /** + * JSON数据,转成Object + */ + private T fromJson(String json, Class clazz){ + return gson.fromJson(json, clazz); + } +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/ShiroUtils.java b/renren-fast/src/main/java/io/renren/common/utils/ShiroUtils.java new file mode 100644 index 0000000..fdf0f14 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/ShiroUtils.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.utils; + +import io.renren.common.exception.RRException; +import io.renren.modules.sys.entity.SysUserEntity; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.session.Session; +import org.apache.shiro.subject.Subject; + +/** + * Shiro工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ShiroUtils { + + public static Session getSession() { + return SecurityUtils.getSubject().getSession(); + } + + public static Subject getSubject() { + return SecurityUtils.getSubject(); + } + + public static SysUserEntity getUserEntity() { + return (SysUserEntity)SecurityUtils.getSubject().getPrincipal(); + } + + public static Long getUserId() { + return getUserEntity().getUserId(); + } + + public static void setSessionAttribute(Object key, Object value) { + getSession().setAttribute(key, value); + } + + public static Object getSessionAttribute(Object key) { + return getSession().getAttribute(key); + } + + public static boolean isLogin() { + return SecurityUtils.getSubject().getPrincipal() != null; + } + + public static String getKaptcha(String key) { + Object kaptcha = getSessionAttribute(key); + if(kaptcha == null){ + throw new RRException("验证码已失效"); + } + getSession().removeAttribute(key); + return kaptcha.toString(); + } + +} diff --git a/renren-fast/src/main/java/io/renren/common/utils/SpringContextUtils.java b/renren-fast/src/main/java/io/renren/common/utils/SpringContextUtils.java new file mode 100644 index 0000000..84e787c --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/utils/SpringContextUtils.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2016-2019 人人开源 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(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-fast/src/main/java/io/renren/common/validator/Assert.java b/renren-fast/src/main/java/io/renren/common/validator/Assert.java new file mode 100644 index 0000000..614e9bc --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/Assert.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator; + +import io.renren.common.exception.RRException; +import org.apache.commons.lang.StringUtils; + +/** + * 数据校验 + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class Assert { + + public static void isBlank(String str, String message) { + if (StringUtils.isBlank(str)) { + throw new RRException(message); + } + } + + public static void isNull(Object object, String message) { + if (object == null) { + throw new RRException(message); + } + } +} diff --git a/renren-fast/src/main/java/io/renren/common/validator/ValidatorUtils.java b/renren-fast/src/main/java/io/renren/common/validator/ValidatorUtils.java new file mode 100644 index 0000000..06cdb0a --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/ValidatorUtils.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + *

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

+ * 版权所有,侵权必究! + */ + +package io.renren.common.validator; + +import io.renren.common.exception.RRException; +import io.renren.common.utils.Constant; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Set; + +/** + * hibernate-validator校验工具类 + * + * 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/ + * + * @author Mark sunlightcs@gmail.com + */ +public class ValidatorUtils { + private static Validator validator; + + static { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + /** + * 校验对象 + * @param object 待校验对象 + * @param groups 待校验的组 + * @throws RRException 校验不通过,则报RRException异常 + */ + public static void validateEntity(Object object, Class... groups) + throws RRException { + Set> constraintViolations = validator.validate(object, groups); + if (!constraintViolations.isEmpty()) { + StringBuilder msg = new StringBuilder(); + for (ConstraintViolation constraint : constraintViolations) { + msg.append(constraint.getMessage()).append("
"); + } + throw new RRException(msg.toString()); + } + } + + public static void validateEntity(Object object, Constant.CloudService type) { + validateEntity(object, type.getValidatorGroupClass()); + } +} diff --git a/renren-fast/src/main/java/io/renren/common/validator/group/AddGroup.java b/renren-fast/src/main/java/io/renren/common/validator/group/AddGroup.java new file mode 100644 index 0000000..81e75ad --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/group/AddGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 新增数据 Group + * + * @author Mark sunlightcs@gmail.com + */ +public interface AddGroup { +} diff --git a/renren-fast/src/main/java/io/renren/common/validator/group/AliyunGroup.java b/renren-fast/src/main/java/io/renren/common/validator/group/AliyunGroup.java new file mode 100644 index 0000000..f05a8cc --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/group/AliyunGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2016-2019 人人开源 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-fast/src/main/java/io/renren/common/validator/group/Group.java b/renren-fast/src/main/java/io/renren/common/validator/group/Group.java new file mode 100644 index 0000000..5004667 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/group/Group.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +import javax.validation.GroupSequence; + +/** + * 定义校验顺序,如果AddGroup组失败,则UpdateGroup组不会再校验 + * + * @author Mark sunlightcs@gmail.com + */ +@GroupSequence({AddGroup.class, UpdateGroup.class}) +public interface Group { + +} diff --git a/renren-fast/src/main/java/io/renren/common/validator/group/QcloudGroup.java b/renren-fast/src/main/java/io/renren/common/validator/group/QcloudGroup.java new file mode 100644 index 0000000..23ad4e9 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/group/QcloudGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2016-2019 人人开源 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-fast/src/main/java/io/renren/common/validator/group/QiniuGroup.java b/renren-fast/src/main/java/io/renren/common/validator/group/QiniuGroup.java new file mode 100644 index 0000000..1297075 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/group/QiniuGroup.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2016-2019 人人开源 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-fast/src/main/java/io/renren/common/validator/group/UpdateGroup.java b/renren-fast/src/main/java/io/renren/common/validator/group/UpdateGroup.java new file mode 100644 index 0000000..a917c55 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/validator/group/UpdateGroup.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.validator.group; + +/** + * 更新数据 Group + * + * @author Mark sunlightcs@gmail.com + */ + +public interface UpdateGroup { + +} diff --git a/renren-fast/src/main/java/io/renren/common/xss/HTMLFilter.java b/renren-fast/src/main/java/io/renren/common/xss/HTMLFilter.java new file mode 100644 index 0000000..3b5de73 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/xss/HTMLFilter.java @@ -0,0 +1,530 @@ +package io.renren.common.xss; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * HTML filtering utility for protecting against XSS (Cross Site Scripting). + * + * This code is licensed LGPLv3 + * + * This code is a Java port of the original work in PHP by Cal Hendersen. + * http://code.iamcal.com/php/lib_filter/ + * + * The trickiest part of the translation was handling the differences in regex handling + * between PHP and Java. These resources were helpful in the process: + * + * http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html + * http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php + * http://www.regular-expressions.info/modifiers.html + * + * A note on naming conventions: instance variables are prefixed with a "v"; global + * constants are in all caps. + * + * Sample use: + * String input = ... + * String clean = new HTMLFilter().filter( input ); + * + * The class is not thread safe. Create a new instance if in doubt. + * + * If you find bugs or have suggestions on improvement (especially regarding + * performance), please contact us. The latest version of this + * source, and our contact details, can be found at http://xss-html-filter.sf.net + * + * @author Joseph O'Connell + * @author Cal Hendersen + * @author Michael Semb Wever + */ +public final class HTMLFilter { + + /** regex flag union representing /si modifiers in php **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("<"); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap(); + + /** set of allowed html elements, along with allowed attributes for each element **/ + private final Map> vAllowed; + /** counts of open tags for each (allowable) html element **/ + private final Map vTagCounts = new HashMap(); + + /** html elements which must always be self-closing (e.g. "") **/ + private final String[] vSelfClosingTags; + /** html elements which must always have separate opening and closing tags (e.g. "") **/ + private final String[] vNeedClosingTags; + /** set of disallowed html elements **/ + private final String[] vDisallowed; + /** attributes which should be checked for valid protocols **/ + private final String[] vProtocolAtts; + /** allowed protocols **/ + private final String[] vAllowedProtocols; + /** tags which should be removed if they contain no content (e.g. "" or "") **/ + private final String[] vRemoveBlanks; + /** entities allowed within html markup **/ + private final String[] vAllowedEntities; + /** flag determining whether comments are allowed in input String. */ + private final boolean stripComment; + private final boolean encodeQuotes; + private boolean vDebug = false; + /** + * flag determining whether to try to make tags when presented with "unbalanced" + * angle brackets (e.g. "" becomes " text "). If set to false, + * unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** Default constructor. + * + */ + public HTMLFilter() { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[]{"img"}; + vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"}; + vDisallowed = new String[]{}; + vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp. + vProtocolAtts = new String[]{"src", "href"}; + vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"}; + vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"}; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = true; + } + + /** Set debug flag to true. Otherwise use default settings. See the default constructor. + * + * @param debug turn debug on with a true argument + */ + public HTMLFilter(final boolean debug) { + this(); + vDebug = debug; + + } + + /** Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + public HTMLFilter(final Map conf) { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() { + vTagCounts.clear(); + } + + private void debug(final String msg) { + if (vDebug) { + Logger.getAnonymousLogger().info(msg); + } + } + + //--------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + //--------------------------------------------------------------- + /** + * given a user submitted input String, filter out any invalid or restricted + * html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) { + reset(); + String s = input; + + debug("************************************************"); + debug(" INPUT: " + input); + + s = escapeComments(s); + debug(" escapeComments: " + s); + + s = balanceHTML(s); + debug(" balanceHTML: " + s); + + s = checkTags(s); + debug(" checkTags: " + s); + + s = processRemoveBlanks(s); + debug("processRemoveBlanks: " + s); + + s = validateEntities(s); + debug(" validateEntites: " + s); + + debug("************************************************\n\n"); + return s; + } + + public boolean isAlwaysMakeTags(){ + return alwaysMakeTags; + } + + public boolean isStripComments(){ + return stripComment; + } + + private String escapeComments(final String s) { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) { + final String match = m.group(1); //(.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) { + if (alwaysMakeTags) { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } else { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + s = buf.toString(); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + for (String key : vTagCounts.keySet()) { + for (int ii = 0; ii < vTagCounts.get(key); ii++) { + s += ""; + } + } + + return s; + } + + private String processRemoveBlanks(final String s) { + String result = s; + for (String tag : vRemoveBlanks) { + if(!P_REMOVE_PAIR_BLANKS.containsKey(tag)){ + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if(!P_REMOVE_SELF_BLANKS.containsKey(tag)){ + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) { + if (!inArray(name, vSelfClosingTags)) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + //debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) { + String params = ""; + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList(); + final List paramValues = new ArrayList(); + while (m2.find()) { + paramNames.add(m2.group(1)); //([a-z0-9]+) + paramValues.add(m2.group(3)); //(.*?) + } + while (m3.find()) { + paramNames.add(m3.group(1)); //([a-z0-9]+) + paramValues.add(m3.group(3)); //([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + +// debug( "paramName='" + paramName + "'" ); +// debug( "paramValue='" + paramValue + "'" ); +// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) { + if (inArray(paramName, vProtocolAtts)) { + paramValue = processParamProtocol(paramValue); + } + params += " " + paramName + "=\"" + paramValue + "\""; + } + } + + if (inArray(name, vSelfClosingTags)) { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) { + ending = ""; + } + + if (ending == null || ending.length() < 1) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } else { + vTagCounts.put(name, 1); + } + } else { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } else { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1, s.length()); + if (s.startsWith("#//")) { + s = "#" + s.substring(3, s.length()); + } + } + } + + return s; + } + + private String decodeEntities(String s) { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) { + final String one = m.group(1); //([^&;]*) + final String two = m.group(2); //(?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s){ + if(encodeQuotes){ + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) { + final String one = m.group(1); //(>|^) + final String two = m.group(2); //([^<]+?) + final String three = m.group(3); //(<|$) + m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, """, two) + three)); + } + m.appendTail(buf); + return buf.toString(); + }else{ + return s; + } + } + + private String checkEntity(final String preamble, final String term) { + + return ";".equals(term) && isValidEntity(preamble) + ? '&' + preamble + : "&" + preamble; + } + + private boolean isValidEntity(final String entity) { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) { + for (String item : array) { + if (item != null && item.equals(s)) { + return true; + } + } + return false; + } + + private boolean allowed(final String name) { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/common/xss/SQLFilter.java b/renren-fast/src/main/java/io/renren/common/xss/SQLFilter.java new file mode 100644 index 0000000..0675ddc --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/xss/SQLFilter.java @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.xss; + +import io.renren.common.exception.RRException; +import org.apache.commons.lang.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 RRException("包含非法字符"); + } + } + + return str; + } +} diff --git a/renren-fast/src/main/java/io/renren/common/xss/XssFilter.java b/renren-fast/src/main/java/io/renren/common/xss/XssFilter.java new file mode 100644 index 0000000..f12921b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/xss/XssFilter.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2016-2019 人人开源 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) throws ServletException { + } + + 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-fast/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java b/renren-fast/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000..75a0e47 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.common.xss; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.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.util.LinkedHashMap; +import java.util.Map; + +/** + * XSS过滤处理 + * + * @author Mark sunlightcs@gmail.com + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + //没被包装过的HttpServletRequest(特殊场景,需要自己过滤) + HttpServletRequest orgRequest; + //html过滤 + private final static HTMLFilter htmlFilter = new HTMLFilter(); + + public XssHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + orgRequest = request; + } + + @Override + public ServletInputStream getInputStream() throws IOException { + //非json类型,直接返回 + if(!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))){ + return super.getInputStream(); + } + + //为空,直接返回 + String json = IOUtils.toString(super.getInputStream(), "utf-8"); + if (StringUtils.isBlank(json)) { + return super.getInputStream(); + } + + //xss过滤 + json = xssEncode(json); + final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("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() throws IOException { + 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 htmlFilter.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; + } + +} diff --git a/renren-fast/src/main/java/io/renren/config/CorsConfig.java b/renren-fast/src/main/java/io/renren/config/CorsConfig.java new file mode 100644 index 0000000..830ffce --- /dev/null +++ b/renren-fast/src/main/java/io/renren/config/CorsConfig.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class CorsConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowCredentials(true) + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .maxAge(3600); + } +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/config/FilterConfig.java b/renren-fast/src/main/java/io/renren/config/FilterConfig.java new file mode 100644 index 0000000..a6687f2 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/config/FilterConfig.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 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-fast/src/main/java/io/renren/config/KaptchaConfig.java b/renren-fast/src/main/java/io/renren/config/KaptchaConfig.java new file mode 100644 index 0000000..d22375b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/config/KaptchaConfig.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + + +/** + * 生成验证码配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class KaptchaConfig { + + @Bean + public DefaultKaptcha producer() { + Properties properties = new Properties(); + properties.put("kaptcha.border", "no"); + properties.put("kaptcha.textproducer.font.color", "black"); + properties.put("kaptcha.textproducer.char.space", "5"); + properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑"); + Config config = new Config(properties); + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } +} diff --git a/renren-fast/src/main/java/io/renren/config/MybatisPlusConfig.java b/renren-fast/src/main/java/io/renren/config/MybatisPlusConfig.java new file mode 100644 index 0000000..05aa984 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/config/MybatisPlusConfig.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +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 PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); + } + +} diff --git a/renren-fast/src/main/java/io/renren/config/RedisConfig.java b/renren-fast/src/main/java/io/renren/config/RedisConfig.java new file mode 100644 index 0000000..97d033b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/config/RedisConfig.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Redis配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class RedisConfig { + @Autowired + private RedisConnectionFactory factory; + + @Bean + public RedisTemplate redisTemplate() { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashKeySerializer(new StringRedisSerializer()); + redisTemplate.setHashValueSerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + redisTemplate.setConnectionFactory(factory); + return redisTemplate; + } + + @Bean + public HashOperations hashOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForHash(); + } + + @Bean + public ValueOperations valueOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForValue(); + } + + @Bean + public ListOperations listOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForList(); + } + + @Bean + public SetOperations setOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForSet(); + } + + @Bean + public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForZSet(); + } +} diff --git a/renren-fast/src/main/java/io/renren/config/ShiroConfig.java b/renren-fast/src/main/java/io/renren/config/ShiroConfig.java new file mode 100644 index 0000000..5184252 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/config/ShiroConfig.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import io.renren.modules.sys.jwt.JWTFilter; +import io.renren.modules.sys.jwt.JWTRealm; +import org.apache.shiro.mgt.SecurityManager; +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.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.Filter; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Shiro配置 + * + * @author Mark sunlightcs@gmail.com + */ +@Configuration +public class ShiroConfig { + + @Bean("securityManager") + public SecurityManager securityManager(JWTRealm jwtRealm) { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(jwtRealm); + securityManager.setRememberMeManager(null); + return securityManager; + } + + @Bean("shiroFilter") + public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); + shiroFilter.setSecurityManager(securityManager); + + //jwt token过滤 + Map filters = new HashMap<>(); + filters.put("jwt", new JWTFilter()); + shiroFilter.setFilters(filters); + + Map filterMap = new LinkedHashMap<>(); + filterMap.put("/webjars/**", "anon"); + filterMap.put("/druid/**", "anon"); + filterMap.put("/app/**", "anon"); + filterMap.put("/sys/login", "anon"); + filterMap.put("/swagger/**", "anon"); + filterMap.put("/v2/api-docs", "anon"); + filterMap.put("/swagger-ui.html", "anon"); + filterMap.put("/swagger-resources/**", "anon"); + filterMap.put("/captcha.jpg", "anon"); + filterMap.put("/aaa.txt", "anon"); + filterMap.put("/**", "jwt"); + 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; + } + +} diff --git a/renren-fast/src/main/java/io/renren/config/SwaggerConfig.java b/renren-fast/src/main/java/io/renren/config/SwaggerConfig.java new file mode 100644 index 0000000..211b6b4 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/config/SwaggerConfig.java @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.config; + +import io.swagger.annotations.ApiOperation; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +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.EnableSwagger2; + +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +@Configuration +@EnableSwagger2 +public class SwaggerConfig implements WebMvcConfigurer { + + @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() + .securitySchemes(security()); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("人人开源") + .description("renren-fast文档") + .termsOfServiceUrl("https://www.renren.io") + .version("3.0.0") + .build(); + } + + private List security() { + return newArrayList( + new ApiKey("token", "token", "header") + ); + } + +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/datasource/annotation/DataSource.java b/renren-fast/src/main/java/io/renren/datasource/annotation/DataSource.java new file mode 100644 index 0000000..1dd140a --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/annotation/DataSource.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.datasource.annotation; + +import java.lang.annotation.*; + +/** + * 多数据源注解 + * + * @author Mark sunlightcs@gmail.com + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface DataSource { + String value() default ""; +} diff --git a/renren-fast/src/main/java/io/renren/datasource/aspect/DataSourceAspect.java b/renren-fast/src/main/java/io/renren/datasource/aspect/DataSourceAspect.java new file mode 100644 index 0000000..3ee6c1f --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/aspect/DataSourceAspect.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.datasource.aspect; + + +import io.renren.datasource.annotation.DataSource; +import io.renren.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 + */ +@Aspect +@Component +@Order(Ordered.HIGHEST_PRECEDENCE) +public class DataSourceAspect { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + @Pointcut("@annotation(io.renren.datasource.annotation.DataSource) " + + "|| @within(io.renren.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-fast/src/main/java/io/renren/datasource/config/DynamicContextHolder.java b/renren-fast/src/main/java/io/renren/datasource/config/DynamicContextHolder.java new file mode 100644 index 0000000..d00c5d0 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/config/DynamicContextHolder.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.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-fast/src/main/java/io/renren/datasource/config/DynamicDataSource.java b/renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSource.java new file mode 100644 index 0000000..7792478 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSource.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.datasource.config; + +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * 多数据源 + * + * @author Mark sunlightcs@gmail.com + */ +public class DynamicDataSource extends AbstractRoutingDataSource { + + @Override + protected Object determineCurrentLookupKey() { + return DynamicContextHolder.peek(); + } + +} diff --git a/renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceConfig.java b/renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceConfig.java new file mode 100644 index 0000000..a0c8ff2 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceConfig.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.datasource.config; + +import com.alibaba.druid.pool.DruidDataSource; +import io.renren.datasource.properties.DataSourceProperties; +import io.renren.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 + */ +@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-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceFactory.java b/renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceFactory.java new file mode 100644 index 0000000..4a688e1 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/config/DynamicDataSourceFactory.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.datasource.config; + +import com.alibaba.druid.pool.DruidDataSource; +import io.renren.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-fast/src/main/java/io/renren/datasource/properties/DataSourceProperties.java b/renren-fast/src/main/java/io/renren/datasource/properties/DataSourceProperties.java new file mode 100644 index 0000000..6ee7ec5 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/properties/DataSourceProperties.java @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.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-fast/src/main/java/io/renren/datasource/properties/DynamicDataSourceProperties.java b/renren-fast/src/main/java/io/renren/datasource/properties/DynamicDataSourceProperties.java new file mode 100644 index 0000000..5759e7b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/datasource/properties/DynamicDataSourceProperties.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2018 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.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-fast/src/main/java/io/renren/modules/app/annotation/Login.java b/renren-fast/src/main/java/io/renren/modules/app/annotation/Login.java new file mode 100644 index 0000000..76ec131 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/annotation/Login.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.annotation; + +import java.lang.annotation.*; + +/** + * app登录效验 + * + * @author Mark sunlightcs@gmail.com + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Login { +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/annotation/LoginUser.java b/renren-fast/src/main/java/io/renren/modules/app/annotation/LoginUser.java new file mode 100644 index 0000000..c7b29da --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/annotation/LoginUser.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.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-fast/src/main/java/io/renren/modules/app/config/WebMvcConfig.java b/renren-fast/src/main/java/io/renren/modules/app/config/WebMvcConfig.java new file mode 100644 index 0000000..c2327a2 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/config/WebMvcConfig.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.config; + +import io.renren.modules.app.interceptor.AuthorizationInterceptor; +import io.renren.modules.app.resolver.LoginUserHandlerMethodArgumentResolver; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +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.util.List; + +/** + * 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("/app/**"); + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(loginUserHandlerMethodArgumentResolver); + } +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/modules/app/controller/AppLoginController.java b/renren-fast/src/main/java/io/renren/modules/app/controller/AppLoginController.java new file mode 100644 index 0000000..9834021 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/controller/AppLoginController.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.controller; + + +import io.renren.common.utils.R; +import io.renren.common.validator.ValidatorUtils; +import io.renren.modules.app.form.LoginForm; +import io.renren.modules.app.service.UserService; +import io.renren.modules.app.utils.JwtUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +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.HashMap; +import java.util.Map; + +/** + * APP登录授权 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/app") +@Api("APP登录接口") +public class AppLoginController { + @Autowired + private UserService userService; + @Autowired + private JwtUtils jwtUtils; + + /** + * 登录 + */ + @PostMapping("login") + @ApiOperation("登录") + public R login(@RequestBody LoginForm form){ + //表单校验 + ValidatorUtils.validateEntity(form); + + //用户登录 + long userId = userService.login(form); + + //生成token + String token = jwtUtils.generateToken(userId); + + Map map = new HashMap<>(); + map.put("token", token); + map.put("expire", jwtUtils.getExpire()); + + return R.ok(map); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/controller/AppRegisterController.java b/renren-fast/src/main/java/io/renren/modules/app/controller/AppRegisterController.java new file mode 100644 index 0000000..89b38af --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/controller/AppRegisterController.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.controller; + + +import io.renren.common.utils.R; +import io.renren.common.validator.ValidatorUtils; +import io.renren.modules.app.entity.UserEntity; +import io.renren.modules.app.form.RegisterForm; +import io.renren.modules.app.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("/app") +@Api("APP注册接口") +public class AppRegisterController { + @Autowired + private UserService userService; + + @PostMapping("register") + @ApiOperation("注册") + public R register(@RequestBody RegisterForm form){ + //表单校验 + ValidatorUtils.validateEntity(form); + + UserEntity user = new UserEntity(); + user.setMobile(form.getMobile()); + user.setUsername(form.getMobile()); + user.setPassword(DigestUtils.sha256Hex(form.getPassword())); + user.setCreateTime(new Date()); + userService.save(user); + + return R.ok(); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/controller/AppTestController.java b/renren-fast/src/main/java/io/renren/modules/app/controller/AppTestController.java new file mode 100644 index 0000000..1965199 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/controller/AppTestController.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.controller; + + +import io.renren.common.utils.R; +import io.renren.modules.app.annotation.Login; +import io.renren.modules.app.annotation.LoginUser; +import io.renren.modules.app.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; + +/** + * APP测试接口 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/app") +@Api("APP测试接口") +public class AppTestController { + + @Login + @GetMapping("userInfo") + @ApiOperation("获取用户信息") + public R userInfo(@LoginUser UserEntity user){ + return R.ok().put("user", user); + } + + @Login + @GetMapping("userId") + @ApiOperation("获取用户ID") + public R userInfo(@RequestAttribute("userId") Integer userId){ + return R.ok().put("userId", userId); + } + + @GetMapping("notToken") + @ApiOperation("忽略Token验证测试") + public R notToken(){ + return R.ok().put("msg", "无需token也能访问。。。"); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/dao/UserDao.java b/renren-fast/src/main/java/io/renren/modules/app/dao/UserDao.java new file mode 100644 index 0000000..cb70950 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/dao/UserDao.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.app.entity.UserEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface UserDao extends BaseMapper { + +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/entity/UserEntity.java b/renren-fast/src/main/java/io/renren/modules/app/entity/UserEntity.java new file mode 100644 index 0000000..5a4b1ed --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/entity/UserEntity.java @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.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("tb_user") +public class UserEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + @TableId + private Long userId; + /** + * 用户名 + */ + private String username; + /** + * 手机号 + */ + private String mobile; + /** + * 密码 + */ + private String password; + /** + * 创建时间 + */ + private Date createTime; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/form/LoginForm.java b/renren-fast/src/main/java/io/renren/modules/app/form/LoginForm.java new file mode 100644 index 0000000..8bd16c5 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/form/LoginForm.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.form; + +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 LoginForm { + @ApiModelProperty(value = "手机号") + @NotBlank(message="手机号不能为空") + private String mobile; + + @ApiModelProperty(value = "密码") + @NotBlank(message="密码不能为空") + private String password; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/form/RegisterForm.java b/renren-fast/src/main/java/io/renren/modules/app/form/RegisterForm.java new file mode 100644 index 0000000..1700de1 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/form/RegisterForm.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.form; + +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 RegisterForm { + @ApiModelProperty(value = "手机号") + @NotBlank(message="手机号不能为空") + private String mobile; + + @ApiModelProperty(value = "密码") + @NotBlank(message="密码不能为空") + private String password; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/interceptor/AuthorizationInterceptor.java b/renren-fast/src/main/java/io/renren/modules/app/interceptor/AuthorizationInterceptor.java new file mode 100644 index 0000000..f7d35de --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/interceptor/AuthorizationInterceptor.java @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.interceptor; + + +import io.jsonwebtoken.Claims; +import io.renren.common.exception.RRException; +import io.renren.modules.app.utils.JwtUtils; +import io.renren.modules.app.annotation.Login; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +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 JwtUtils jwtUtils; + + 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; + } + + //获取用户凭证 + String token = request.getHeader(jwtUtils.getHeader()); + if(StringUtils.isBlank(token)){ + token = request.getParameter(jwtUtils.getHeader()); + } + + //凭证为空 + if(StringUtils.isBlank(token)){ + throw new RRException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value()); + } + + Claims claims = jwtUtils.getClaimByToken(token); + if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){ + throw new RRException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value()); + } + + //设置userId到request里,后续根据userId,获取用户信息 + request.setAttribute(USER_KEY, Long.parseLong(claims.getSubject())); + + return true; + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/resolver/LoginUserHandlerMethodArgumentResolver.java b/renren-fast/src/main/java/io/renren/modules/app/resolver/LoginUserHandlerMethodArgumentResolver.java new file mode 100644 index 0000000..5597179 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/resolver/LoginUserHandlerMethodArgumentResolver.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.resolver; + +import io.renren.modules.app.annotation.LoginUser; +import io.renren.modules.app.entity.UserEntity; +import io.renren.modules.app.interceptor.AuthorizationInterceptor; +import io.renren.modules.app.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.getById((Long)object); + + return user; + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/service/UserService.java b/renren-fast/src/main/java/io/renren/modules/app/service/UserService.java new file mode 100644 index 0000000..b111552 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/service/UserService.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.app.entity.UserEntity; +import io.renren.modules.app.form.LoginForm; + +/** + * 用户 + * + * @author Mark sunlightcs@gmail.com + */ +public interface UserService extends IService { + + UserEntity queryByMobile(String mobile); + + /** + * 用户登录 + * @param form 登录表单 + * @return 返回用户ID + */ + long login(LoginForm form); +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/service/impl/UserServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/app/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..c6b2451 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/service/impl/UserServiceImpl.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.service.impl; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.exception.RRException; +import io.renren.common.validator.Assert; +import io.renren.modules.app.dao.UserDao; +import io.renren.modules.app.entity.UserEntity; +import io.renren.modules.app.form.LoginForm; +import io.renren.modules.app.service.UserService; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.stereotype.Service; + + +@Service("userService") +public class UserServiceImpl extends ServiceImpl implements UserService { + + @Override + public UserEntity queryByMobile(String mobile) { + return baseMapper.selectOne(new QueryWrapper().eq("mobile", mobile)); + } + + @Override + public long login(LoginForm form) { + UserEntity user = queryByMobile(form.getMobile()); + Assert.isNull(user, "手机号或密码错误"); + + //密码错误 + if(!user.getPassword().equals(DigestUtils.sha256Hex(form.getPassword()))){ + throw new RRException("手机号或密码错误"); + } + + return user.getUserId(); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/app/utils/JwtUtils.java b/renren-fast/src/main/java/io/renren/modules/app/utils/JwtUtils.java new file mode 100644 index 0000000..05ec088 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/app/utils/JwtUtils.java @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.app.utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * jwt工具类 + * + * @author Mark sunlightcs@gmail.com + */ +@ConfigurationProperties(prefix = "renren.jwt") +@Component +public class JwtUtils { + private Logger logger = LoggerFactory.getLogger(getClass()); + + private String secret; + private long expire; + private String header; + + /** + * 生成jwt token + */ + public String generateToken(long userId) { + Date nowDate = new Date(); + //过期时间 + Date expireDate = new Date(nowDate.getTime() + expire * 1000); + + return Jwts.builder() + .setHeaderParam("typ", "JWT") + .setSubject(userId+"") + .setIssuedAt(nowDate) + .setExpiration(expireDate) + .signWith(SignatureAlgorithm.HS512, secret) + .compact(); + } + + public Claims getClaimByToken(String token) { + try { + return Jwts.parser() + .setSigningKey(secret) + .parseClaimsJws(token) + .getBody(); + }catch (Exception e){ + logger.debug("validate is token error ", e); + return null; + } + } + + /** + * token是否过期 + * @return true:过期 + */ + public boolean isTokenExpired(Date expiration) { + return expiration.before(new Date()); + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public long getExpire() { + return expire; + } + + public void setExpire(long expire) { + this.expire = expire; + } + + public String getHeader() { + return header; + } + + public void setHeader(String header) { + this.header = header; + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/config/ScheduleConfig.java b/renren-fast/src/main/java/io/renren/modules/job/config/ScheduleConfig.java new file mode 100644 index 0000000..ab12541 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/config/ScheduleConfig.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016-2019 人人开源 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-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java b/renren-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java new file mode 100644 index 0000000..4c3edaf --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobController.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.controller; + +import io.renren.common.annotation.SysLog; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.R; +import io.renren.common.validator.ValidatorUtils; +import io.renren.modules.job.entity.ScheduleJobEntity; +import io.renren.modules.job.service.ScheduleJobService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/schedule") +public class ScheduleJobController { + @Autowired + private ScheduleJobService scheduleJobService; + + /** + * 定时任务列表 + */ + @RequestMapping("/list") + @RequiresPermissions("sys:schedule:list") + public R list(@RequestParam Map params){ + PageUtils page = scheduleJobService.queryPage(params); + + return R.ok().put("page", page); + } + + /** + * 定时任务信息 + */ + @RequestMapping("/info/{jobId}") + @RequiresPermissions("sys:schedule:info") + public R info(@PathVariable("jobId") Long jobId){ + ScheduleJobEntity schedule = scheduleJobService.getById(jobId); + + return R.ok().put("schedule", schedule); + } + + /** + * 保存定时任务 + */ + @SysLog("保存定时任务") + @RequestMapping("/save") + @RequiresPermissions("sys:schedule:save") + public R save(@RequestBody ScheduleJobEntity scheduleJob){ + ValidatorUtils.validateEntity(scheduleJob); + + scheduleJobService.saveJob(scheduleJob); + + return R.ok(); + } + + /** + * 修改定时任务 + */ + @SysLog("修改定时任务") + @RequestMapping("/update") + @RequiresPermissions("sys:schedule:update") + public R update(@RequestBody ScheduleJobEntity scheduleJob){ + ValidatorUtils.validateEntity(scheduleJob); + + scheduleJobService.update(scheduleJob); + + return R.ok(); + } + + /** + * 删除定时任务 + */ + @SysLog("删除定时任务") + @RequestMapping("/delete") + @RequiresPermissions("sys:schedule:delete") + public R delete(@RequestBody Long[] jobIds){ + scheduleJobService.deleteBatch(jobIds); + + return R.ok(); + } + + /** + * 立即执行任务 + */ + @SysLog("立即执行任务") + @RequestMapping("/run") + @RequiresPermissions("sys:schedule:run") + public R run(@RequestBody Long[] jobIds){ + scheduleJobService.run(jobIds); + + return R.ok(); + } + + /** + * 暂停定时任务 + */ + @SysLog("暂停定时任务") + @RequestMapping("/pause") + @RequiresPermissions("sys:schedule:pause") + public R pause(@RequestBody Long[] jobIds){ + scheduleJobService.pause(jobIds); + + return R.ok(); + } + + /** + * 恢复定时任务 + */ + @SysLog("恢复定时任务") + @RequestMapping("/resume") + @RequiresPermissions("sys:schedule:resume") + public R resume(@RequestBody Long[] jobIds){ + scheduleJobService.resume(jobIds); + + return R.ok(); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java b/renren-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java new file mode 100644 index 0000000..b24d2ab --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/controller/ScheduleJobLogController.java @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.controller; + +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.R; +import io.renren.modules.job.entity.ScheduleJobLogEntity; +import io.renren.modules.job.service.ScheduleJobLogService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/scheduleLog") +public class ScheduleJobLogController { + @Autowired + private ScheduleJobLogService scheduleJobLogService; + + /** + * 定时任务日志列表 + */ + @RequestMapping("/list") + @RequiresPermissions("sys:schedule:log") + public R list(@RequestParam Map params){ + PageUtils page = scheduleJobLogService.queryPage(params); + + return R.ok().put("page", page); + } + + /** + * 定时任务日志信息 + */ + @RequestMapping("/info/{logId}") + public R info(@PathVariable("logId") Long logId){ + ScheduleJobLogEntity log = scheduleJobLogService.getById(logId); + + return R.ok().put("log", log); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java b/renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java new file mode 100644 index 0000000..c5baa59 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobDao.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +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 BaseMapper { + + /** + * 批量更新状态 + */ + int updateBatch(Map map); +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java b/renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java new file mode 100644 index 0000000..e760dc8 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/dao/ScheduleJobLogDao.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.job.entity.ScheduleJobLogEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface ScheduleJobLogDao extends BaseMapper { + +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java b/renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java new file mode 100644 index 0000000..22363fb --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobEntity.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Date; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("schedule_job") +public class ScheduleJobEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 任务调度参数key + */ + public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY"; + + /** + * 任务id + */ + @TableId + private Long jobId; + + /** + * spring bean名称 + */ + @NotBlank(message="bean名称不能为空") + private String beanName; + + /** + * 参数 + */ + private String params; + + /** + * cron表达式 + */ + @NotBlank(message="cron表达式不能为空") + private String cronExpression; + + /** + * 任务状态 + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java b/renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java new file mode 100644 index 0000000..8587f90 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/entity/ScheduleJobLogEntity.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.fasterxml.jackson.annotation.JsonFormat; +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 logId; + + /** + * 任务id + */ + private Long jobId; + + /** + * spring bean名称 + */ + private String beanName; + + /** + * 参数 + */ + private String params; + + /** + * 任务状态 0:成功 1:失败 + */ + private Integer status; + + /** + * 失败信息 + */ + private String error; + + /** + * 耗时(单位:毫秒) + */ + private Integer times; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date createTime; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java b/renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java new file mode 100644 index 0000000..9e21fd8 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobLogService.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.PageUtils; +import io.renren.modules.job.entity.ScheduleJobLogEntity; + +import java.util.Map; + +/** + * 定时任务日志 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ScheduleJobLogService extends IService { + + PageUtils queryPage(Map params); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobService.java b/renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobService.java new file mode 100644 index 0000000..118f926 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/service/ScheduleJobService.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.PageUtils; +import io.renren.modules.job.entity.ScheduleJobEntity; + +import java.util.Map; + +/** + * 定时任务 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ScheduleJobService extends IService { + + PageUtils queryPage(Map params); + + /** + * 保存定时任务 + */ + void saveJob(ScheduleJobEntity scheduleJob); + + /** + * 更新定时任务 + */ + void update(ScheduleJobEntity scheduleJob); + + /** + * 批量删除定时任务 + */ + void deleteBatch(Long[] jobIds); + + /** + * 批量更新定时任务状态 + */ + int updateBatch(Long[] jobIds, int status); + + /** + * 立即执行 + */ + void run(Long[] jobIds); + + /** + * 暂停运行 + */ + void pause(Long[] jobIds); + + /** + * 恢复运行 + */ + void resume(Long[] jobIds); +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java new file mode 100644 index 0000000..5a55d4b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobLogServiceImpl.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.Query; +import io.renren.modules.job.dao.ScheduleJobLogDao; +import io.renren.modules.job.entity.ScheduleJobLogEntity; +import io.renren.modules.job.service.ScheduleJobLogService; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service("scheduleJobLogService") +public class ScheduleJobLogServiceImpl extends ServiceImpl implements ScheduleJobLogService { + + @Override + public PageUtils queryPage(Map params) { + String jobId = (String)params.get("jobId"); + + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper().like(StringUtils.isNotBlank(jobId),"job_id", jobId) + ); + + return new PageUtils(page); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java new file mode 100644 index 0000000..56a8509 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/service/impl/ScheduleJobServiceImpl.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.utils.Constant; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.Query; +import io.renren.modules.job.dao.ScheduleJobDao; +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.lang.StringUtils; +import org.quartz.CronTrigger; +import org.quartz.Scheduler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import java.util.*; + +@Service("scheduleJobService") +public class ScheduleJobServiceImpl extends ServiceImpl implements ScheduleJobService { + @Autowired + private Scheduler scheduler; + + /** + * 项目启动时,初始化定时器 + */ + @PostConstruct + public void init(){ + List scheduleJobList = this.list(); + for(ScheduleJobEntity scheduleJob : scheduleJobList){ + CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getJobId()); + //如果不存在,则创建 + if(cronTrigger == null) { + ScheduleUtils.createScheduleJob(scheduler, scheduleJob); + }else { + ScheduleUtils.updateScheduleJob(scheduler, scheduleJob); + } + } + } + + @Override + public PageUtils queryPage(Map params) { + String beanName = (String)params.get("beanName"); + + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper ().like(StringUtils.isNotBlank(beanName),"bean_name", beanName) + ); + + return new PageUtils(page); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveJob(ScheduleJobEntity scheduleJob) { + scheduleJob.setCreateTime(new Date()); + scheduleJob.setStatus(Constant.ScheduleStatus.NORMAL.getValue()); + this.save(scheduleJob); + + ScheduleUtils.createScheduleJob(scheduler, scheduleJob); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ScheduleJobEntity scheduleJob) { + ScheduleUtils.updateScheduleJob(scheduler, scheduleJob); + + this.updateById(scheduleJob); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteBatch(Long[] jobIds) { + for(Long jobId : jobIds){ + ScheduleUtils.deleteScheduleJob(scheduler, jobId); + } + + //删除数据 + this.removeByIds(Arrays.asList(jobIds)); + } + + @Override + public int updateBatch(Long[] jobIds, int status){ + Map map = new HashMap<>(2); + map.put("list", Arrays.asList(jobIds)); + map.put("status", status); + return baseMapper.updateBatch(map); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void run(Long[] jobIds) { + for(Long jobId : jobIds){ + ScheduleUtils.run(scheduler, this.getById(jobId)); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void pause(Long[] jobIds) { + for(Long jobId : jobIds){ + ScheduleUtils.pauseJob(scheduler, jobId); + } + + updateBatch(jobIds, Constant.ScheduleStatus.PAUSE.getValue()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void resume(Long[] jobIds) { + for(Long jobId : jobIds){ + ScheduleUtils.resumeJob(scheduler, jobId); + } + + updateBatch(jobIds, Constant.ScheduleStatus.NORMAL.getValue()); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/task/ITask.java b/renren-fast/src/main/java/io/renren/modules/job/task/ITask.java new file mode 100644 index 0000000..3c386f5 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/task/ITask.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.task; + +/** + * 定时任务接口,所有定时任务都要实现该接口 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ITask { + + /** + * 执行定时任务接口 + * + * @param params 参数,多参数使用JSON数据 + */ + void run(String params); +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/modules/job/task/TestTask.java b/renren-fast/src/main/java/io/renren/modules/job/task/TestTask.java new file mode 100644 index 0000000..9459cfc --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/task/TestTask.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2016-2019 人人开源 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); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleJob.java b/renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleJob.java new file mode 100644 index 0000000..0f269e6 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleJob.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.utils; + +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.apache.commons.lang.StringUtils; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +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) throws JobExecutionException { + ScheduleJobEntity scheduleJob = (ScheduleJobEntity) context.getMergedJobDataMap() + .get(ScheduleJobEntity.JOB_PARAM_KEY); + + //获取spring bean + ScheduleJobLogService scheduleJobLogService = (ScheduleJobLogService) SpringContextUtils.getBean("scheduleJobLogService"); + + //数据库保存执行记录 + ScheduleJobLogEntity log = new ScheduleJobLogEntity(); + log.setJobId(scheduleJob.getJobId()); + log.setBeanName(scheduleJob.getBeanName()); + log.setParams(scheduleJob.getParams()); + log.setCreateTime(new Date()); + + //任务开始时间 + long startTime = System.currentTimeMillis(); + + try { + //执行任务 + logger.debug("任务准备执行,任务ID:" + scheduleJob.getJobId()); + + 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); + //任务状态 0:成功 1:失败 + log.setStatus(0); + + logger.debug("任务执行完毕,任务ID:" + scheduleJob.getJobId() + " 总共耗时:" + times + "毫秒"); + } catch (Exception e) { + logger.error("任务执行失败,任务ID:" + scheduleJob.getJobId(), e); + + //任务执行总时长 + long times = System.currentTimeMillis() - startTime; + log.setTimes((int)times); + + //任务状态 0:成功 1:失败 + log.setStatus(1); + log.setError(StringUtils.substring(e.toString(), 0, 2000)); + }finally { + scheduleJobLogService.save(log); + } + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java b/renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java new file mode 100644 index 0000000..974f8bf --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/job/utils/ScheduleUtils.java @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.job.utils; + +import io.renren.common.exception.RRException; +import io.renren.common.utils.Constant; +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 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 RRException("获取定时任务CronTrigger出现异常", e); + } + } + + /** + * 创建定时任务 + */ + public static void createScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + //构建job信息 + JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(scheduleJob.getJobId())).build(); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + //按新的cronExpression表达式构建一个新的trigger + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getJobId())).withSchedule(scheduleBuilder).build(); + + //放入参数,运行时的方法可以获取 + jobDetail.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob); + + scheduler.scheduleJob(jobDetail, trigger); + + //暂停任务 + if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ + pauseJob(scheduler, scheduleJob.getJobId()); + } + } catch (SchedulerException e) { + throw new RRException("创建定时任务失败", e); + } + } + + /** + * 更新定时任务 + */ + public static void updateScheduleJob(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId()); + + //表达式调度构建器 + CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()) + .withMisfireHandlingInstructionDoNothing(); + + CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId()); + + //按新的cronExpression表达式重新构建trigger + trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); + + //参数 + trigger.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob); + + scheduler.rescheduleJob(triggerKey, trigger); + + //暂停任务 + if(scheduleJob.getStatus() == Constant.ScheduleStatus.PAUSE.getValue()){ + pauseJob(scheduler, scheduleJob.getJobId()); + } + + } catch (SchedulerException e) { + throw new RRException("更新定时任务失败", e); + } + } + + /** + * 立即执行任务 + */ + public static void run(Scheduler scheduler, ScheduleJobEntity scheduleJob) { + try { + //参数 + JobDataMap dataMap = new JobDataMap(); + dataMap.put(ScheduleJobEntity.JOB_PARAM_KEY, scheduleJob); + + scheduler.triggerJob(getJobKey(scheduleJob.getJobId()), dataMap); + } catch (SchedulerException e) { + throw new RRException("立即执行定时任务失败", e); + } + } + + /** + * 暂停任务 + */ + public static void pauseJob(Scheduler scheduler, Long jobId) { + try { + scheduler.pauseJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RRException("暂停定时任务失败", e); + } + } + + /** + * 恢复任务 + */ + public static void resumeJob(Scheduler scheduler, Long jobId) { + try { + scheduler.resumeJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RRException("暂停定时任务失败", e); + } + } + + /** + * 删除定时任务 + */ + public static void deleteScheduleJob(Scheduler scheduler, Long jobId) { + try { + scheduler.deleteJob(getJobKey(jobId)); + } catch (SchedulerException e) { + throw new RRException("删除定时任务失败", e); + } + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java b/renren-fast/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java new file mode 100644 index 0000000..5ea513f --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import com.aliyun.oss.OSSClient; +import io.renren.common.exception.RRException; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/** + * 阿里云存储 + * + * @author Mark sunlightcs@gmail.com + */ +public class AliyunCloudStorageService extends CloudStorageService { + private OSSClient client; + + public AliyunCloudStorageService(CloudStorageConfig config){ + this.config = config; + + //初始化 + init(); + } + + private void init(){ + client = new OSSClient(config.getAliyunEndPoint(), config.getAliyunAccessKeyId(), + config.getAliyunAccessKeySecret()); + } + + @Override + public String upload(byte[] data, String path) { + return upload(new ByteArrayInputStream(data), path); + } + + @Override + public String upload(InputStream inputStream, String path) { + try { + client.putObject(config.getAliyunBucketName(), path, inputStream); + } catch (Exception e){ + throw new RRException("上传文件失败,请检查配置信息", 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)); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java b/renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java new file mode 100644 index 0000000..ea5179c --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageConfig.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 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 +public class CloudStorageConfig implements Serializable { + private static final long serialVersionUID = 1L; + + //类型 1:七牛 2:阿里云 3:腾讯云 + @Range(min=1, max=3, message = "类型错误") + private Integer type; + + //七牛绑定的域名 + @NotBlank(message="七牛绑定的域名不能为空", groups = QiniuGroup.class) + @URL(message = "七牛绑定的域名格式不正确", groups = QiniuGroup.class) + private String qiniuDomain; + //七牛路径前缀 + private String qiniuPrefix; + //七牛ACCESS_KEY + @NotBlank(message="七牛AccessKey不能为空", groups = QiniuGroup.class) + private String qiniuAccessKey; + //七牛SECRET_KEY + @NotBlank(message="七牛SecretKey不能为空", groups = QiniuGroup.class) + private String qiniuSecretKey; + //七牛存储空间名 + @NotBlank(message="七牛空间名不能为空", groups = QiniuGroup.class) + private String qiniuBucketName; + + //阿里云绑定的域名 + @NotBlank(message="阿里云绑定的域名不能为空", groups = AliyunGroup.class) + @URL(message = "阿里云绑定的域名格式不正确", groups = AliyunGroup.class) + private String aliyunDomain; + //阿里云路径前缀 + private String aliyunPrefix; + //阿里云EndPoint + @NotBlank(message="阿里云EndPoint不能为空", groups = AliyunGroup.class) + private String aliyunEndPoint; + //阿里云AccessKeyId + @NotBlank(message="阿里云AccessKeyId不能为空", groups = AliyunGroup.class) + private String aliyunAccessKeyId; + //阿里云AccessKeySecret + @NotBlank(message="阿里云AccessKeySecret不能为空", groups = AliyunGroup.class) + private String aliyunAccessKeySecret; + //阿里云BucketName + @NotBlank(message="阿里云BucketName不能为空", groups = AliyunGroup.class) + private String aliyunBucketName; + + //腾讯云绑定的域名 + @NotBlank(message="腾讯云绑定的域名不能为空", groups = QcloudGroup.class) + @URL(message = "腾讯云绑定的域名格式不正确", groups = QcloudGroup.class) + private String qcloudDomain; + //腾讯云路径前缀 + private String qcloudPrefix; + //腾讯云AppId + @NotNull(message="腾讯云AppId不能为空", groups = QcloudGroup.class) + private Integer qcloudAppId; + //腾讯云SecretId + @NotBlank(message="腾讯云SecretId不能为空", groups = QcloudGroup.class) + private String qcloudSecretId; + //腾讯云SecretKey + @NotBlank(message="腾讯云SecretKey不能为空", groups = QcloudGroup.class) + private String qcloudSecretKey; + //腾讯云BucketName + @NotBlank(message="腾讯云BucketName不能为空", groups = QcloudGroup.class) + private String qcloudBucketName; + //腾讯云COS所属地区 + @NotBlank(message="所属地区不能为空", groups = QcloudGroup.class) + private String qcloudRegion; + + +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java b/renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java new file mode 100644 index 0000000..96d1093 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import io.renren.common.utils.DateUtils; +import org.apache.commons.lang.StringUtils; + +import java.io.InputStream; +import java.util.Date; +import java.util.UUID; + +/** + * 云存储(支持七牛、阿里云、腾讯云、又拍云) + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class CloudStorageService { + /** 云存储配置信息 */ + 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-fast/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java b/renren-fast/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java new file mode 100644 index 0000000..e72dbb1 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/cloud/OSSFactory.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + + +import io.renren.common.utils.ConfigConstant; +import io.renren.common.utils.Constant; +import io.renren.common.utils.SpringContextUtils; +import io.renren.modules.sys.service.SysConfigService; + +/** + * 文件上传Factory + * + * @author Mark sunlightcs@gmail.com + */ +public final class OSSFactory { + private static SysConfigService sysConfigService; + + static { + OSSFactory.sysConfigService = (SysConfigService) SpringContextUtils.getBean("sysConfigService"); + } + + public static CloudStorageService build(){ + //获取云存储配置信息 + CloudStorageConfig config = sysConfigService.getConfigObject(ConfigConstant.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; + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java b/renren-fast/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java new file mode 100644 index 0000000..d1d2170 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + + +import com.alibaba.fastjson.JSONObject; +import com.qcloud.cos.COSClient; +import com.qcloud.cos.ClientConfig; +import com.qcloud.cos.request.UploadFileRequest; +import com.qcloud.cos.sign.Credentials; +import io.renren.common.exception.RRException; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; + +/** + * 腾讯云存储 + * + * @author Mark sunlightcs@gmail.com + */ +public class QcloudCloudStorageService extends CloudStorageService { + private COSClient client; + + public QcloudCloudStorageService(CloudStorageConfig config){ + this.config = config; + + //初始化 + init(); + } + + private void init(){ + Credentials credentials = new Credentials(config.getQcloudAppId(), config.getQcloudSecretId(), + config.getQcloudSecretKey()); + + //初始化客户端配置 + ClientConfig clientConfig = new ClientConfig(); + //设置bucket所在的区域,华南:gz 华北:tj 华东:sh + clientConfig.setRegion(config.getQcloudRegion()); + + client = new COSClient(clientConfig, credentials); + } + + @Override + public String upload(byte[] data, String path) { + //腾讯云必需要以"/"开头 + if(!path.startsWith("/")) { + path = "/" + path; + } + + //上传到腾讯云 + UploadFileRequest request = new UploadFileRequest(config.getQcloudBucketName(), path, data); + String response = client.uploadFile(request); + + JSONObject jsonObject = JSONObject.parseObject(response); + if(jsonObject.getInteger("code") != 0) { + throw new RRException("文件上传失败," + jsonObject.getString("message")); + } + + return config.getQcloudDomain() + 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 RRException("上传文件失败", e); + } + } + + @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)); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java b/renren-fast/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java new file mode 100644 index 0000000..db4fab9 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.cloud; + +import com.qiniu.common.Zone; +import com.qiniu.http.Response; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; +import com.qiniu.util.Auth; +import io.renren.common.exception.RRException; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; + +/** + * 七牛云存储 + * + * @author Mark sunlightcs@gmail.com + */ +public class QiniuCloudStorageService extends CloudStorageService { + private UploadManager uploadManager; + private String token; + + public QiniuCloudStorageService(CloudStorageConfig config){ + this.config = config; + + //初始化 + init(); + } + + private void init(){ + uploadManager = new UploadManager(new Configuration(Zone.autoZone())); + 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 RuntimeException("上传七牛出错:" + res.toString()); + } + } catch (Exception e) { + throw new RRException("上传文件失败,请核对七牛配置信息", 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 RRException("上传文件失败", 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-fast/src/main/java/io/renren/modules/oss/controller/SysOssController.java b/renren-fast/src/main/java/io/renren/modules/oss/controller/SysOssController.java new file mode 100644 index 0000000..e8830ac --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/controller/SysOssController.java @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.controller; + +import com.google.gson.Gson; +import io.renren.common.exception.RRException; +import io.renren.common.utils.ConfigConstant; +import io.renren.common.utils.Constant; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.R; +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.SysConfigService; +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 java.util.Arrays; +import java.util.Date; +import java.util.Map; + +/** + * 文件上传 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("sys/oss") +public class SysOssController { + @Autowired + private SysOssService sysOssService; + @Autowired + private SysConfigService sysConfigService; + + private final static String KEY = ConfigConstant.CLOUD_STORAGE_CONFIG_KEY; + + /** + * 列表 + */ + @GetMapping("/list") + @RequiresPermissions("sys:oss:all") + public R list(@RequestParam Map params){ + PageUtils page = sysOssService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 云存储配置信息 + */ + @GetMapping("/config") + @RequiresPermissions("sys:oss:all") + public R config(){ + CloudStorageConfig config = sysConfigService.getConfigObject(KEY, CloudStorageConfig.class); + + return R.ok().put("config", config); + } + + + /** + * 保存云存储配置信息 + */ + @PostMapping("/saveConfig") + @RequiresPermissions("sys:oss:all") + public R saveConfig(@RequestBody CloudStorageConfig config){ + //校验类型 + ValidatorUtils.validateEntity(config); + ValidatorUtils.validateEntity(config, Constant.CloudService.getByValue(config.getType())); + + sysConfigService.updateValueByKey(KEY, new Gson().toJson(config)); + + return R.ok(); + } + + + /** + * 上传文件 + */ + @PostMapping("/upload") + @RequiresPermissions("sys:oss:all") + public R upload(@RequestParam("file") MultipartFile file) throws Exception { + if (file.isEmpty()) { + throw new RRException("上传文件不能为空"); + } + + //上传文件 + String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + String url = OSSFactory.build().uploadSuffix(file.getBytes(), suffix); + + //保存文件信息 + SysOssEntity ossEntity = new SysOssEntity(); + ossEntity.setUrl(url); + ossEntity.setCreateDate(new Date()); + sysOssService.save(ossEntity); + + return R.ok().put("url", url); + } + + + /** + * 删除 + */ + @PostMapping("/delete") + @RequiresPermissions("sys:oss:all") + public R delete(@RequestBody Long[] ids){ + sysOssService.removeByIds(Arrays.asList(ids)); + + return R.ok(); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/dao/SysOssDao.java b/renren-fast/src/main/java/io/renren/modules/oss/dao/SysOssDao.java new file mode 100644 index 0000000..e5f04f6 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/dao/SysOssDao.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.oss.entity.SysOssEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 文件上传 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysOssDao extends BaseMapper { + +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java b/renren-fast/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java new file mode 100644 index 0000000..2086eb7 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/entity/SysOssEntity.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.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("sys_oss") +public class SysOssEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId + private Long id; + //URL地址 + private String url; + //创建时间 + private Date createDate; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/service/SysOssService.java b/renren-fast/src/main/java/io/renren/modules/oss/service/SysOssService.java new file mode 100644 index 0000000..c77c00f --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/service/SysOssService.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.PageUtils; +import io.renren.modules.oss.entity.SysOssEntity; + +import java.util.Map; + +/** + * 文件上传 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysOssService extends IService { + + PageUtils queryPage(Map params); +} diff --git a/renren-fast/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java new file mode 100644 index 0000000..ffaa194 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/oss/service/impl/SysOssServiceImpl.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.oss.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.Query; +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("sysOssService") +public class SysOssServiceImpl extends ServiceImpl implements SysOssService { + + @Override + public PageUtils queryPage(Map params) { + IPage page = this.page( + new Query().getPage(params) + ); + + return new PageUtils(page); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/controller/AbstractController.java b/renren-fast/src/main/java/io/renren/modules/sys/controller/AbstractController.java new file mode 100644 index 0000000..608ecb3 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/controller/AbstractController.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.modules.sys.entity.SysUserEntity; +import org.apache.shiro.SecurityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Controller公共组件 + * + * @author Mark sunlightcs@gmail.com + */ +public abstract class AbstractController { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + protected SysUserEntity getUser() { + return (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); + } + + protected Long getUserId() { + return getUser().getUserId(); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/controller/SysConfigController.java b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysConfigController.java new file mode 100644 index 0000000..5314f39 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysConfigController.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + + +import io.renren.common.annotation.SysLog; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.R; +import io.renren.common.validator.ValidatorUtils; +import io.renren.modules.sys.entity.SysConfigEntity; +import io.renren.modules.sys.service.SysConfigService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * 系统配置信息 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/config") +public class SysConfigController extends AbstractController { + @Autowired + private SysConfigService sysConfigService; + + /** + * 所有配置列表 + */ + @GetMapping("/list") + @RequiresPermissions("sys:config:list") + public R list(@RequestParam Map params){ + PageUtils page = sysConfigService.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 配置信息 + */ + @GetMapping("/info/{id}") + @RequiresPermissions("sys:config:info") + public R info(@PathVariable("id") Long id){ + SysConfigEntity config = sysConfigService.getById(id); + + return R.ok().put("config", config); + } + + /** + * 保存配置 + */ + @SysLog("保存配置") + @PostMapping("/save") + @RequiresPermissions("sys:config:save") + public R save(@RequestBody SysConfigEntity config){ + ValidatorUtils.validateEntity(config); + + sysConfigService.saveConfig(config); + + return R.ok(); + } + + /** + * 修改配置 + */ + @SysLog("修改配置") + @PostMapping("/update") + @RequiresPermissions("sys:config:update") + public R update(@RequestBody SysConfigEntity config){ + ValidatorUtils.validateEntity(config); + + sysConfigService.update(config); + + return R.ok(); + } + + /** + * 删除配置 + */ + @SysLog("删除配置") + @PostMapping("/delete") + @RequiresPermissions("sys:config:delete") + public R delete(@RequestBody Long[] ids){ + sysConfigService.deleteBatch(ids); + + return R.ok(); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/controller/SysLogController.java b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysLogController.java new file mode 100644 index 0000000..e69af10 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysLogController.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.R; +import io.renren.modules.sys.service.SysLogService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +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.ResponseBody; + +import java.util.Map; + + +/** + * 系统日志 + * + * @author Mark sunlightcs@gmail.com + */ +@Controller +@RequestMapping("/sys/log") +public class SysLogController { + @Autowired + private SysLogService sysLogService; + + /** + * 列表 + */ + @ResponseBody + @GetMapping("/list") + @RequiresPermissions("sys:log:list") + public R list(@RequestParam Map params){ + PageUtils page = sysLogService.queryPage(params); + + return R.ok().put("page", page); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/controller/SysLoginController.java b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysLoginController.java new file mode 100644 index 0000000..bb09155 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysLoginController.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.utils.R; +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.form.SysLoginForm; +import io.renren.modules.sys.service.SysCaptchaService; +import io.renren.modules.sys.service.SysUserService; +import io.renren.modules.sys.service.SysUserTokenService; +import org.apache.commons.io.IOUtils; +import org.apache.shiro.crypto.hash.Sha256Hash; +import org.springframework.beans.factory.annotation.Autowired; +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.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.Map; + +/** + * 登录相关 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +public class SysLoginController extends AbstractController { + @Autowired + private SysUserService sysUserService; + @Autowired + private SysUserTokenService sysUserTokenService; + @Autowired + private SysCaptchaService sysCaptchaService; + + /** + * 验证码 + */ + @GetMapping("captcha.jpg") + public void captcha(HttpServletResponse response, String uuid)throws IOException { + response.setHeader("Cache-Control", "no-store, no-cache"); + response.setContentType("image/jpeg"); + + //获取图片验证码 + BufferedImage image = sysCaptchaService.getCaptcha(uuid); + + ServletOutputStream out = response.getOutputStream(); + ImageIO.write(image, "jpg", out); + IOUtils.closeQuietly(out); + } + + /** + * 登录 + */ + @PostMapping("/sys/login") + public Map login(@RequestBody SysLoginForm form)throws IOException { + boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha()); + if(!captcha){ + return R.error("验证码不正确"); + } + + //用户信息 + SysUserEntity user = sysUserService.queryByUserName(form.getUsername()); + + //账号不存在、密码错误 + if(user == null || !user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) { + return R.error("账号或密码不正确"); + } + + //账号锁定 + if(user.getStatus() == 0){ + return R.error("账号已被锁定,请联系管理员"); + } + + //生成token,并保存到数据库 + R r = sysUserTokenService.createToken(user.getUserId()); + return r; + } + + + /** + * 退出 + */ + @PostMapping("/sys/logout") + public R logout() { + sysUserTokenService.logout(getUserId()); + return R.ok(); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/controller/SysMenuController.java b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysMenuController.java new file mode 100644 index 0000000..6b9eb08 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysMenuController.java @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.SysLog; +import io.renren.common.exception.RRException; +import io.renren.common.utils.Constant; +import io.renren.common.utils.R; +import io.renren.modules.sys.entity.SysMenuEntity; +import io.renren.modules.sys.service.ShiroService; +import io.renren.modules.sys.service.SysMenuService; +import org.apache.commons.lang.StringUtils; +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; +import java.util.Objects; +import java.util.Set; +import java.util.Collections; + + +/** + * 系统菜单 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/menu") +public class SysMenuController extends AbstractController { + @Autowired + private SysMenuService sysMenuService; + @Autowired + private ShiroService shiroService; + + /** + * 导航菜单 + */ + @GetMapping("/nav") + public R nav(){ + List menuList = sysMenuService.getUserMenuList(getUserId()); + Set permissions = shiroService.getUserPermissions(getUserId()); + return R.ok().put("menuList", menuList).put("permissions", permissions); + } + + /** + * 所有菜单列表 + */ + @GetMapping("/list") + @RequiresPermissions("sys:menu:list") + public List list(){ + List menuList = sysMenuService.list(); + + //查询完成 对此list直接排序 + Collections.sort(menuList); + + HashMap menuMap = new HashMap<>(12); + for (SysMenuEntity s : menuList) { + menuMap.put(s.getMenuId(), s); + } + for (SysMenuEntity s : menuList) { + SysMenuEntity parent = menuMap.get(s.getParentId()); + if (Objects.nonNull(parent)) { + s.setParentName(parent.getName()); + } + + } + + + return menuList; + } + + /** + * 选择菜单(添加、修改菜单) + */ + @GetMapping("/select") + @RequiresPermissions("sys:menu:select") + public R select(){ + //查询列表数据 + List menuList = sysMenuService.queryNotButtonList(); + + //添加顶级菜单 + SysMenuEntity root = new SysMenuEntity(); + root.setMenuId(0L); + root.setName("一级菜单"); + root.setParentId(-1L); + root.setOpen(true); + menuList.add(root); + + return R.ok().put("menuList", menuList); + } + + /** + * 菜单信息 + */ + @GetMapping("/info/{menuId}") + @RequiresPermissions("sys:menu:info") + public R info(@PathVariable("menuId") Long menuId){ + SysMenuEntity menu = sysMenuService.getById(menuId); + return R.ok().put("menu", menu); + } + + /** + * 保存 + */ + @SysLog("保存菜单") + @PostMapping("/save") + @RequiresPermissions("sys:menu:save") + public R save(@RequestBody SysMenuEntity menu){ + //数据校验 + verifyForm(menu); + + sysMenuService.save(menu); + + return R.ok(); + } + + /** + * 修改 + */ + @SysLog("修改菜单") + @PostMapping("/update") + @RequiresPermissions("sys:menu:update") + public R update(@RequestBody SysMenuEntity menu){ + //数据校验 + verifyForm(menu); + + sysMenuService.updateById(menu); + + return R.ok(); + } + + /** + * 删除 + */ + @SysLog("删除菜单") + @PostMapping("/delete/{menuId}") + @RequiresPermissions("sys:menu:delete") + public R delete(@PathVariable("menuId") long menuId){ + if(menuId <= 31){ + return R.error("系统菜单,不能删除"); + } + + //判断是否有子菜单或按钮 + List menuList = sysMenuService.queryListParentId(menuId); + if(menuList.size() > 0){ + return R.error("请先删除子菜单或按钮"); + } + + sysMenuService.delete(menuId); + + return R.ok(); + } + + /** + * 验证参数是否正确 + */ + private void verifyForm(SysMenuEntity menu){ + if(StringUtils.isBlank(menu.getName())){ + throw new RRException("菜单名称不能为空"); + } + + if(menu.getParentId() == null){ + throw new RRException("上级菜单不能为空"); + } + + //菜单 + if(menu.getType() == Constant.MenuType.MENU.getValue()){ + if(StringUtils.isBlank(menu.getUrl())){ + throw new RRException("菜单URL不能为空"); + } + } + + //上级菜单类型 + int parentType = Constant.MenuType.CATALOG.getValue(); + if(menu.getParentId() != 0){ + SysMenuEntity parentMenu = sysMenuService.getById(menu.getParentId()); + parentType = parentMenu.getType(); + } + + //目录、菜单 + if(menu.getType() == Constant.MenuType.CATALOG.getValue() || + menu.getType() == Constant.MenuType.MENU.getValue()){ + if(parentType != Constant.MenuType.CATALOG.getValue()){ + throw new RRException("上级菜单只能为目录类型"); + } + return ; + } + + //按钮 + if(menu.getType() == Constant.MenuType.BUTTON.getValue()){ + if(parentType != Constant.MenuType.MENU.getValue()){ + throw new RRException("上级菜单只能为菜单类型"); + } + return ; + } + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/controller/SysRoleController.java b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysRoleController.java new file mode 100644 index 0000000..5a6f9d8 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysRoleController.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.SysLog; +import io.renren.common.utils.Constant; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.R; +import io.renren.common.validator.ValidatorUtils; +import io.renren.modules.sys.entity.SysRoleEntity; +import io.renren.modules.sys.service.SysRoleMenuService; +import io.renren.modules.sys.service.SysRoleService; +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; +import java.util.Map; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/role") +public class SysRoleController extends AbstractController { + @Autowired + private SysRoleService sysRoleService; + @Autowired + private SysRoleMenuService sysRoleMenuService; + + /** + * 角色列表 + */ + @GetMapping("/list") + @RequiresPermissions("sys:role:list") + public R list(@RequestParam Map params){ + //如果不是超级管理员,则只查询自己创建的角色列表 + if(getUserId() != Constant.SUPER_ADMIN){ + params.put("createUserId", getUserId()); + } + + PageUtils page = sysRoleService.queryPage(params); + + return R.ok().put("page", page); + } + + /** + * 角色列表 + */ + @GetMapping("/select") + @RequiresPermissions("sys:role:select") + public R select(){ + Map map = new HashMap<>(); + + //如果不是超级管理员,则只查询自己所拥有的角色列表 + if(getUserId() != Constant.SUPER_ADMIN){ + map.put("create_user_id", getUserId()); + } + List list = (List) sysRoleService.listByMap(map); + + return R.ok().put("list", list); + } + + /** + * 角色信息 + */ + @GetMapping("/info/{roleId}") + @RequiresPermissions("sys:role:info") + public R info(@PathVariable("roleId") Long roleId){ + SysRoleEntity role = sysRoleService.getById(roleId); + + //查询角色对应的菜单 + List menuIdList = sysRoleMenuService.queryMenuIdList(roleId); + role.setMenuIdList(menuIdList); + + return R.ok().put("role", role); + } + + /** + * 保存角色 + */ + @SysLog("保存角色") + @PostMapping("/save") + @RequiresPermissions("sys:role:save") + public R save(@RequestBody SysRoleEntity role){ + ValidatorUtils.validateEntity(role); + + role.setCreateUserId(getUserId()); + sysRoleService.saveRole(role); + + return R.ok(); + } + + /** + * 修改角色 + */ + @SysLog("修改角色") + @PostMapping("/update") + @RequiresPermissions("sys:role:update") + public R update(@RequestBody SysRoleEntity role){ + ValidatorUtils.validateEntity(role); + + role.setCreateUserId(getUserId()); + sysRoleService.update(role); + + return R.ok(); + } + + /** + * 删除角色 + */ + @SysLog("删除角色") + @PostMapping("/delete") + @RequiresPermissions("sys:role:delete") + public R delete(@RequestBody Long[] roleIds){ + sysRoleService.deleteBatch(roleIds); + + return R.ok(); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/controller/SysUserController.java b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysUserController.java new file mode 100644 index 0000000..27c2990 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/controller/SysUserController.java @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.controller; + +import io.renren.common.annotation.SysLog; +import io.renren.common.utils.Constant; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.R; +import io.renren.common.validator.Assert; +import io.renren.common.validator.ValidatorUtils; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.UpdateGroup; +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.form.PasswordForm; +import io.renren.modules.sys.service.SysUserRoleService; +import io.renren.modules.sys.service.SysUserService; +import org.apache.commons.lang.ArrayUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.apache.shiro.crypto.hash.Sha256Hash; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@RestController +@RequestMapping("/sys/user") +public class SysUserController extends AbstractController { + @Autowired + private SysUserService sysUserService; + @Autowired + private SysUserRoleService sysUserRoleService; + + + /** + * 所有用户列表 + */ + @GetMapping("/list") + @RequiresPermissions("sys:user:list") + public R list(@RequestParam Map params){ + //只有超级管理员,才能查看所有管理员列表 + if(getUserId() != Constant.SUPER_ADMIN){ + params.put("createUserId", getUserId()); + } + PageUtils page = sysUserService.queryPage(params); + + return R.ok().put("page", page); + } + + /** + * 获取登录的用户信息 + */ + @GetMapping("/info") + public R info(){ + return R.ok().put("user", getUser()); + } + + /** + * 修改登录用户密码 + */ + @SysLog("修改密码") + @PostMapping("/password") + public R password(@RequestBody PasswordForm form){ + Assert.isBlank(form.getNewPassword(), "新密码不为能空"); + + //sha256加密 + String password = new Sha256Hash(form.getPassword(), getUser().getSalt()).toHex(); + //sha256加密 + String newPassword = new Sha256Hash(form.getNewPassword(), getUser().getSalt()).toHex(); + + //更新密码 + boolean flag = sysUserService.updatePassword(getUserId(), password, newPassword); + if(!flag){ + return R.error("原密码不正确"); + } + + return R.ok(); + } + + /** + * 用户信息 + */ + @GetMapping("/info/{userId}") + @RequiresPermissions("sys:user:info") + public R info(@PathVariable("userId") Long userId){ + SysUserEntity user = sysUserService.getById(userId); + + //获取用户所属的角色列表 + List roleIdList = sysUserRoleService.queryRoleIdList(userId); + user.setRoleIdList(roleIdList); + + return R.ok().put("user", user); + } + + /** + * 保存用户 + */ + @SysLog("保存用户") + @PostMapping("/save") + @RequiresPermissions("sys:user:save") + public R save(@RequestBody SysUserEntity user){ + ValidatorUtils.validateEntity(user, AddGroup.class); + + user.setCreateUserId(getUserId()); + sysUserService.saveUser(user); + + return R.ok(); + } + + /** + * 修改用户 + */ + @SysLog("修改用户") + @PostMapping("/update") + @RequiresPermissions("sys:user:update") + public R update(@RequestBody SysUserEntity user){ + ValidatorUtils.validateEntity(user, UpdateGroup.class); + + user.setCreateUserId(getUserId()); + sysUserService.update(user); + + return R.ok(); + } + + /** + * 删除用户 + */ + @SysLog("删除用户") + @PostMapping("/delete") + @RequiresPermissions("sys:user:delete") + public R delete(@RequestBody Long[] userIds){ + if(ArrayUtils.contains(userIds, 1L)){ + return R.error("系统管理员不能删除"); + } + + if(ArrayUtils.contains(userIds, getUserId())){ + return R.error("当前用户不能删除"); + } + + sysUserService.deleteBatch(userIds); + + return R.ok(); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysCaptchaDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysCaptchaDao.java new file mode 100644 index 0000000..80d6d18 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysCaptchaDao.java @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysCaptchaEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 验证码 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysCaptchaDao extends BaseMapper { + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysConfigDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysConfigDao.java new file mode 100644 index 0000000..0132d72 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysConfigDao.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysConfigEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 系统配置信息 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysConfigDao extends BaseMapper { + + /** + * 根据key,查询value + */ + SysConfigEntity queryByKey(String paramKey); + + /** + * 根据key,更新value + */ + int updateValueByKey(@Param("paramKey") String paramKey, @Param("paramValue") String paramValue); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysLogDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysLogDao.java new file mode 100644 index 0000000..afd984d --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysLogDao.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysLogEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 系统日志 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysLogDao extends BaseMapper { + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java new file mode 100644 index 0000000..4339a8c --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysMenuDao.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysMenuEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysMenuDao extends BaseMapper { + + /** + * 根据父菜单,查询子菜单 + * @param parentId 父菜单ID + */ + List queryListParentId(Long parentId); + + /** + * 获取不包含按钮的菜单列表 + */ + List queryNotButtonList(); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java new file mode 100644 index 0000000..e99c8ea --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleDao.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysRoleEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 角色管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysRoleDao extends BaseMapper { + + /** + * 查询用户创建的角色ID列表 + */ + List queryRoleIdList(Long createUserId); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java new file mode 100644 index 0000000..4dc0429 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysRoleMenuDao.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +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 BaseMapper { + + /** + * 根据角色ID,获取菜单ID列表 + */ + List queryMenuIdList(Long roleId); + + /** + * 根据角色ID数组,批量删除 + */ + int deleteBatch(Long[] roleIds); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserDao.java new file mode 100644 index 0000000..333c00c --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserDao.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysUserEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserDao extends BaseMapper { + + /** + * 查询用户的所有权限 + * @param userId 用户ID + */ + List queryAllPerms(Long userId); + + /** + * 查询用户的所有菜单ID + */ + List queryAllMenuId(Long userId); + + /** + * 根据用户名,查询系统用户 + */ + SysUserEntity queryByUserName(String username); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserRoleDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserRoleDao.java new file mode 100644 index 0000000..298bbd6 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserRoleDao.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysUserRoleEntity; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 用户与角色对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserRoleDao extends BaseMapper { + + /** + * 根据用户ID,获取角色ID列表 + */ + List queryRoleIdList(Long userId); + + + /** + * 根据角色ID数组,批量删除 + */ + int deleteBatch(Long[] roleIds); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserTokenDao.java b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserTokenDao.java new file mode 100644 index 0000000..546cd1d --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserTokenDao.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.renren.modules.sys.entity.SysUserTokenEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 系统用户Token + * + * @author Mark sunlightcs@gmail.com + */ +@Mapper +public interface SysUserTokenDao extends BaseMapper { + + SysUserTokenEntity queryByToken(String token); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysCaptchaEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysCaptchaEntity.java new file mode 100644 index 0000000..70fd694 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysCaptchaEntity.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * 系统验证码 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_captcha") +public class SysCaptchaEntity { + @TableId(type = IdType.INPUT) + private String uuid; + /** + * 验证码 + */ + private String code; + /** + * 过期时间 + */ + private Date expireTime; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysConfigEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysConfigEntity.java new file mode 100644 index 0000000..83c83c3 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysConfigEntity.java @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 系统配置信息 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_config") +public class SysConfigEntity { + @TableId + private Long id; + @NotBlank(message="参数名不能为空") + private String paramKey; + @NotBlank(message="参数值不能为空") + private String paramValue; + private String remark; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysLogEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysLogEntity.java new file mode 100644 index 0000000..6f1a4bd --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysLogEntity.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.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("sys_log") +public class SysLogEntity implements Serializable { + private static final long serialVersionUID = 1L; + @TableId + private Long id; + //用户名 + private String username; + //用户操作 + private String operation; + //请求方法 + private String method; + //请求参数 + private String params; + //执行时长(毫秒) + private Long time; + //IP地址 + private String ip; + //创建时间 + private Date createDate; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java new file mode 100644 index 0000000..6bc3797 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysMenuEntity.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +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.ArrayList; +import java.util.List; + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_menu") +public class SysMenuEntity implements Serializable,Comparable { + private static final long serialVersionUID = 1L; + + /** + * 菜单ID + */ + @TableId + private Long menuId; + + /** + * 父菜单ID,一级菜单为0 + */ + private Long parentId; + + /** + * 父菜单名称 + */ + @TableField(exist=false) + private String parentName; + + /** + * 菜单名称 + */ + private String name; + + /** + * 菜单URL + */ + private String url; + + /** + * 授权(多个用逗号分隔,如:user:list,user:create) + */ + private String perms; + + /** + * 类型 0:目录 1:菜单 2:按钮 + */ + private Integer type; + + /** + * 菜单图标 + */ + private String icon; + + /** + * 排序 + */ + private Integer orderNum; + + /** + * ztree属性 + */ + @TableField(exist=false) + private Boolean open; + + @TableField(exist=false) + private List list=new ArrayList<>(); + + @Override + public int compareTo(SysMenuEntity o) { + return this.getOrderNum()-o.getOrderNum(); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java new file mode 100644 index 0000000..086035b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleEntity.java @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_role") +public class SysRoleEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 角色ID + */ + @TableId + private Long roleId; + + /** + * 角色名称 + */ + @NotBlank(message="角色名称不能为空") + private String roleName; + + /** + * 备注 + */ + private String remark; + + /** + * 创建者ID + */ + private Long createUserId; + + @TableField(exist=false) + private List menuIdList; + + /** + * 创建时间 + */ + private Date createTime; + + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java new file mode 100644 index 0000000..d603707 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysRoleMenuEntity.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_role_menu") +public class SysRoleMenuEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId + private Long id; + + /** + * 角色ID + */ + private Long roleId; + + /** + * 菜单ID + */ + private Long menuId; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java new file mode 100644 index 0000000..ed268ca --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.renren.common.validator.group.AddGroup; +import io.renren.common.validator.group.UpdateGroup; +import lombok.Data; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_user") +public class SysUserEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + @TableId + private Long userId; + + /** + * 用户名 + */ + @NotBlank(message="用户名不能为空", groups = {AddGroup.class, UpdateGroup.class}) + private String username; + + /** + * 密码 + */ + @NotBlank(message="密码不能为空", groups = AddGroup.class) + private String password; + + /** + * 盐 + */ + private String salt; + + /** + * 邮箱 + */ + @NotBlank(message="邮箱不能为空", groups = {AddGroup.class, UpdateGroup.class}) + @Email(message="邮箱格式不正确", groups = {AddGroup.class, UpdateGroup.class}) + private String email; + + /** + * 手机号 + */ + private String mobile; + + /** + * 状态 0:禁用 1:正常 + */ + private Integer status; + + /** + * 角色ID列表 + */ + @TableField(exist=false) + private List roleIdList; + + /** + * 创建者ID + */ + private Long createUserId; + + /** + * 创建时间 + */ + private Date createTime; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserRoleEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserRoleEntity.java new file mode 100644 index 0000000..8f34484 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserRoleEntity.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户与角色对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +@TableName("sys_user_role") +public class SysUserRoleEntity implements Serializable { + private static final long serialVersionUID = 1L; + @TableId + private Long id; + + /** + * 用户ID + */ + private Long userId; + + /** + * 角色ID + */ + private Long roleId; + + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserTokenEntity.java b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserTokenEntity.java new file mode 100644 index 0000000..70de984 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserTokenEntity.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +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("sys_user_token") +public class SysUserTokenEntity implements Serializable { + private static final long serialVersionUID = 1L; + + //用户ID + @TableId(type = IdType.INPUT) + private Long userId; + //token + private String token; + //过期时间 + private Date expireTime; + //更新时间 + private Date updateTime; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/form/PasswordForm.java b/renren-fast/src/main/java/io/renren/modules/sys/form/PasswordForm.java new file mode 100644 index 0000000..61a077b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/form/PasswordForm.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.form; + +import lombok.Data; + +/** + * 密码表单 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public class PasswordForm { + /** + * 原密码 + */ + private String password; + /** + * 新密码 + */ + private String newPassword; + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/form/SysLoginForm.java b/renren-fast/src/main/java/io/renren/modules/sys/form/SysLoginForm.java new file mode 100644 index 0000000..abeb6fc --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/form/SysLoginForm.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.form; + +import lombok.Data; + +/** + * 登录表单 + * + * @author Mark sunlightcs@gmail.com + */ +@Data +public class SysLoginForm { + private String username; + private String password; + private String captcha; + private String uuid; + + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTFilter.java b/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTFilter.java new file mode 100644 index 0000000..8703668 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTFilter.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.jwt; + +import com.google.gson.Gson; +import io.renren.common.utils.HttpContextUtils; +import io.renren.common.utils.R; +import org.apache.commons.lang.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; + +/** + * jwt token过滤器 + * + * @author Mark sunlightcs@gmail.com + */ +public class JWTFilter 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 JWTToken(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.setHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); + + String json = new Gson().toJson(R.error(HttpStatus.SC_UNAUTHORIZED, "invalid token")); + + 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(); + R r = R.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("token"); + + //如果header中不存在token,则从参数中获取token + if(StringUtils.isBlank(token)){ + token = httpRequest.getParameter("token"); + } + + return token; + } + + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTRealm.java b/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTRealm.java new file mode 100644 index 0000000..a6e7c5c --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTRealm.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.jwt; + +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.entity.SysUserTokenEntity; +import io.renren.modules.sys.service.ShiroService; +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.Set; + +/** + * 认证 + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class JWTRealm extends AuthorizingRealm { + @Autowired + private ShiroService shiroService; + + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof JWTToken; + } + + /** + * 授权(验证权限时调用) + */ + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal(); + Long userId = user.getUserId(); + + //用户权限列表 + Set permsSet = shiroService.getUserPermissions(userId); + + 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.queryByToken(accessToken); + //token失效 + if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){ + throw new IncorrectCredentialsException("token失效,请重新登录"); + } + + //查询用户信息 + SysUserEntity user = shiroService.queryUser(tokenEntity.getUserId()); + //账号锁定 + if(user.getStatus() == 0){ + throw new LockedAccountException("账号已被锁定,请联系管理员"); + } + + SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName()); + return info; + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTToken.java b/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTToken.java new file mode 100644 index 0000000..e810b1d --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/jwt/JWTToken.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.jwt; + + +import org.apache.shiro.authc.AuthenticationToken; + +/** + * token + * + * @author Mark sunlightcs@gmail.com + */ +public class JWTToken implements AuthenticationToken { + private String token; + + public JWTToken(String token){ + this.token = token; + } + + @Override + public String getPrincipal() { + return token; + } + + @Override + public Object getCredentials() { + return token; + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/jwt/TokenGenerator.java b/renren-fast/src/main/java/io/renren/modules/sys/jwt/TokenGenerator.java new file mode 100644 index 0000000..27baaee --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/jwt/TokenGenerator.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.jwt; + +import io.renren.common.exception.RRException; + +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[] hexCode = "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(hexCode[(b >> 4) & 0xF]); + r.append(hexCode[(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 RRException("生成Token失败", e); + } + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/redis/SysConfigRedis.java b/renren-fast/src/main/java/io/renren/modules/sys/redis/SysConfigRedis.java new file mode 100644 index 0000000..e6857e7 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/redis/SysConfigRedis.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.redis; + + +import io.renren.common.utils.RedisKeys; +import io.renren.common.utils.RedisUtils; +import io.renren.modules.sys.entity.SysConfigEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 系统配置Redis + * + * @author Mark sunlightcs@gmail.com + */ +@Component +public class SysConfigRedis { + @Autowired + private RedisUtils redisUtils; + + public void saveOrUpdate(SysConfigEntity config) { + if(config == null){ + return ; + } + String key = RedisKeys.getSysConfigKey(config.getParamKey()); + redisUtils.set(key, config); + } + + public void delete(String configKey) { + String key = RedisKeys.getSysConfigKey(configKey); + redisUtils.delete(key); + } + + public SysConfigEntity get(String configKey){ + String key = RedisKeys.getSysConfigKey(configKey); + return redisUtils.get(key, SysConfigEntity.class); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/ShiroService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/ShiroService.java new file mode 100644 index 0000000..5872f57 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/ShiroService.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.entity.SysUserTokenEntity; + +import java.util.Set; + +/** + * shiro相关接口 + * + * @author Mark sunlightcs@gmail.com + */ +public interface ShiroService { + /** + * 获取用户权限列表 + */ + Set getUserPermissions(long userId); + + SysUserTokenEntity queryByToken(String token); + + /** + * 根据用户ID,查询用户 + * @param userId + */ + SysUserEntity queryUser(Long userId); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysCaptchaService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysCaptchaService.java new file mode 100644 index 0000000..0eeaf47 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysCaptchaService.java @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.sys.entity.SysCaptchaEntity; + +import java.awt.image.BufferedImage; + +/** + * 验证码 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysCaptchaService extends IService { + + /** + * 获取图片验证码 + */ + BufferedImage getCaptcha(String uuid); + + /** + * 验证码效验 + * @param uuid uuid + * @param code 验证码 + * @return true:成功 false:失败 + */ + boolean validate(String uuid, String code); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysConfigService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysConfigService.java new file mode 100644 index 0000000..0f48610 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysConfigService.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.PageUtils; +import io.renren.modules.sys.entity.SysConfigEntity; + +import java.util.Map; + +/** + * 系统配置信息 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysConfigService extends IService { + + PageUtils queryPage(Map params); + + /** + * 保存配置信息 + */ + public void saveConfig(SysConfigEntity config); + + /** + * 更新配置信息 + */ + public void update(SysConfigEntity config); + + /** + * 根据key,更新value + */ + public void updateValueByKey(String key, String value); + + /** + * 删除配置信息 + */ + public void deleteBatch(Long[] ids); + + /** + * 根据key,获取配置的value值 + * + * @param key key + */ + public String getValue(String key); + + /** + * 根据key,获取value的Object对象 + * @param key key + * @param clazz Object对象 + */ + public T getConfigObject(String key, Class clazz); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysLogService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysLogService.java new file mode 100644 index 0000000..71e8f4f --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysLogService.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.PageUtils; +import io.renren.modules.sys.entity.SysLogEntity; + +import java.util.Map; + + +/** + * 系统日志 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysLogService extends IService { + + PageUtils queryPage(Map params); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysMenuService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysMenuService.java new file mode 100644 index 0000000..b20056b --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysMenuService.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.sys.entity.SysMenuEntity; + +import java.util.List; + + +/** + * 菜单管理 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysMenuService extends IService { + + /** + * 根据父菜单,查询子菜单 + * @param parentId 父菜单ID + * @param menuIdList 用户菜单ID + */ + List queryListParentId(Long parentId, List menuIdList); + + /** + * 根据父菜单,查询子菜单 + * @param parentId 父菜单ID + */ + List queryListParentId(Long parentId); + + /** + * 获取不包含按钮的菜单列表 + */ + List queryNotButtonList(); + + /** + * 获取用户菜单列表 + */ + List getUserMenuList(Long userId); + + /** + * 删除 + */ + void delete(Long menuId); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java new file mode 100644 index 0000000..14bd509 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleMenuService.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.sys.entity.SysRoleMenuEntity; + +import java.util.List; + + + +/** + * 角色与菜单对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysRoleMenuService extends IService { + + void saveOrUpdate(Long roleId, List menuIdList); + + /** + * 根据角色ID,获取菜单ID列表 + */ + List queryMenuIdList(Long roleId); + + /** + * 根据角色ID数组,批量删除 + */ + int deleteBatch(Long[] roleIds); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleService.java new file mode 100644 index 0000000..92ae5c6 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysRoleService.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.PageUtils; +import io.renren.modules.sys.entity.SysRoleEntity; + +import java.util.List; +import java.util.Map; + + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysRoleService extends IService { + + PageUtils queryPage(Map params); + + void saveRole(SysRoleEntity role); + + void update(SysRoleEntity role); + + void deleteBatch(Long[] roleIds); + + + /** + * 查询用户创建的角色ID列表 + */ + List queryRoleIdList(Long createUserId); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserRoleService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserRoleService.java new file mode 100644 index 0000000..b4441fa --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserRoleService.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.modules.sys.entity.SysUserRoleEntity; + +import java.util.List; + + + +/** + * 用户与角色对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysUserRoleService extends IService { + + void saveOrUpdate(Long userId, List roleIdList); + + /** + * 根据用户ID,获取角色ID列表 + */ + List queryRoleIdList(Long userId); + + /** + * 根据角色ID数组,批量删除 + */ + int deleteBatch(Long[] roleIds); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserService.java new file mode 100644 index 0000000..e29b038 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserService.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.PageUtils; +import io.renren.modules.sys.entity.SysUserEntity; + +import java.util.List; +import java.util.Map; + + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysUserService extends IService { + + PageUtils queryPage(Map params); + + /** + * 查询用户的所有权限 + * @param userId 用户ID + */ + List queryAllPerms(Long userId); + + /** + * 查询用户的所有菜单ID + */ + List queryAllMenuId(Long userId); + + /** + * 根据用户名,查询系统用户 + */ + SysUserEntity queryByUserName(String username); + + /** + * 保存用户 + */ + void saveUser(SysUserEntity user); + + /** + * 修改用户 + */ + void update(SysUserEntity user); + + /** + * 删除用户 + */ + void deleteBatch(Long[] userIds); + + /** + * 修改密码 + * @param userId 用户ID + * @param password 原密码 + * @param newPassword 新密码 + */ + boolean updatePassword(Long userId, String password, String newPassword); +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserTokenService.java b/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserTokenService.java new file mode 100644 index 0000000..f4ecb5a --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/SysUserTokenService.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.renren.common.utils.R; +import io.renren.modules.sys.entity.SysUserTokenEntity; + +/** + * 用户Token + * + * @author Mark sunlightcs@gmail.com + */ +public interface SysUserTokenService extends IService { + + /** + * 生成token + * @param userId 用户ID + */ + R createToken(long userId); + + /** + * 退出,修改token值 + * @param userId 用户ID + */ + void logout(long userId); + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/ShiroServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/ShiroServiceImpl.java new file mode 100644 index 0000000..12230bc --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/ShiroServiceImpl.java @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import io.renren.common.utils.Constant; +import io.renren.modules.sys.dao.SysMenuDao; +import io.renren.modules.sys.dao.SysUserDao; +import io.renren.modules.sys.dao.SysUserTokenDao; +import io.renren.modules.sys.entity.SysMenuEntity; +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.entity.SysUserTokenEntity; +import io.renren.modules.sys.service.ShiroService; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +public class ShiroServiceImpl implements ShiroService { + @Autowired + private SysMenuDao sysMenuDao; + @Autowired + private SysUserDao sysUserDao; + @Autowired + private SysUserTokenDao sysUserTokenDao; + + @Override + public Set getUserPermissions(long userId) { + List permsList; + + //系统管理员,拥有最高权限 + if(userId == Constant.SUPER_ADMIN){ + List menuList = sysMenuDao.selectList(null); + permsList = new ArrayList<>(menuList.size()); + for(SysMenuEntity menu : menuList){ + permsList.add(menu.getPerms()); + } + }else{ + permsList = sysUserDao.queryAllPerms(userId); + } + //用户权限列表 + Set permsSet = new HashSet<>(); + for(String perms : permsList){ + if(StringUtils.isBlank(perms)){ + continue; + } + permsSet.addAll(Arrays.asList(perms.trim().split(","))); + } + return permsSet; + } + + @Override + public SysUserTokenEntity queryByToken(String token) { + return sysUserTokenDao.queryByToken(token); + } + + @Override + public SysUserEntity queryUser(Long userId) { + return sysUserDao.selectById(userId); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysCaptchaServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysCaptchaServiceImpl.java new file mode 100644 index 0000000..b9c991e --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysCaptchaServiceImpl.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016-2019 人人开源 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.extension.service.impl.ServiceImpl; +import com.google.code.kaptcha.Producer; +import io.renren.common.exception.RRException; +import io.renren.common.utils.DateUtils; +import io.renren.modules.sys.dao.SysCaptchaDao; +import io.renren.modules.sys.entity.SysCaptchaEntity; +import io.renren.modules.sys.service.SysCaptchaService; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.awt.image.BufferedImage; +import java.util.Date; + +/** + * 验证码 + * + * @author Mark sunlightcs@gmail.com + */ +@Service("sysCaptchaService") +public class SysCaptchaServiceImpl extends ServiceImpl implements SysCaptchaService { + @Autowired + private Producer producer; + + @Override + public BufferedImage getCaptcha(String uuid) { + if(StringUtils.isBlank(uuid)){ + throw new RRException("uuid不能为空"); + } + //生成文字验证码 + String code = producer.createText(); + + SysCaptchaEntity captchaEntity = new SysCaptchaEntity(); + captchaEntity.setUuid(uuid); + captchaEntity.setCode(code); + //5分钟后过期 + captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 5)); + this.save(captchaEntity); + + return producer.createImage(code); + } + + @Override + public boolean validate(String uuid, String code) { + SysCaptchaEntity captchaEntity = this.getOne(new QueryWrapper().eq("uuid", uuid)); + if(captchaEntity == null){ + return false; + } + + //删除验证码 + this.removeById(uuid); + + if(captchaEntity.getCode().equalsIgnoreCase(code) && captchaEntity.getExpireTime().getTime() >= System.currentTimeMillis()){ + return true; + } + + return false; + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..e62763d --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.gson.Gson; +import io.renren.common.exception.RRException; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.Query; +import io.renren.modules.sys.dao.SysConfigDao; +import io.renren.modules.sys.entity.SysConfigEntity; +import io.renren.modules.sys.redis.SysConfigRedis; +import io.renren.modules.sys.service.SysConfigService; +import org.apache.commons.lang.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.Map; + +@Service("sysConfigService") +public class SysConfigServiceImpl extends ServiceImpl implements SysConfigService { + @Autowired + private SysConfigRedis sysConfigRedis; + + @Override + public PageUtils queryPage(Map params) { + String paramKey = (String)params.get("paramKey"); + + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + .like(StringUtils.isNotBlank(paramKey),"param_key", paramKey) + .eq("status", 1) + ); + + return new PageUtils(page); + } + + @Override + public void saveConfig(SysConfigEntity config) { + this.save(config); + sysConfigRedis.saveOrUpdate(config); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysConfigEntity config) { + this.updateById(config); + sysConfigRedis.saveOrUpdate(config); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateValueByKey(String key, String value) { + baseMapper.updateValueByKey(key, value); + sysConfigRedis.delete(key); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteBatch(Long[] ids) { + for(Long id : ids){ + SysConfigEntity config = this.getById(id); + sysConfigRedis.delete(config.getParamKey()); + } + + this.removeByIds(Arrays.asList(ids)); + } + + @Override + public String getValue(String key) { + SysConfigEntity config = sysConfigRedis.get(key); + if(config == null){ + config = baseMapper.queryByKey(key); + sysConfigRedis.saveOrUpdate(config); + } + + return config == null ? null : config.getParamValue(); + } + + @Override + public T getConfigObject(String key, Class clazz) { + String value = getValue(key); + if(StringUtils.isNotBlank(value)){ + return new Gson().fromJson(value, clazz); + } + + try { + return clazz.newInstance(); + } catch (Exception e) { + throw new RRException("获取参数失败"); + } + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysLogServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysLogServiceImpl.java new file mode 100644 index 0000000..517f1ec --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysLogServiceImpl.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.Query; +import io.renren.modules.sys.dao.SysLogDao; +import io.renren.modules.sys.entity.SysLogEntity; +import io.renren.modules.sys.service.SysLogService; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.Map; + + +@Service("sysLogService") +public class SysLogServiceImpl extends ServiceImpl implements SysLogService { + + @Override + public PageUtils queryPage(Map params) { + String key = (String)params.get("key"); + + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper().like(StringUtils.isNotBlank(key),"username", key) + ); + + return new PageUtils(page); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java new file mode 100644 index 0000000..63a2064 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysMenuServiceImpl.java @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2016-2019 人人开源 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.extension.service.impl.ServiceImpl; +import io.renren.common.utils.Constant; +import io.renren.common.utils.MapUtils; +import io.renren.modules.sys.dao.SysMenuDao; +import io.renren.modules.sys.entity.SysMenuEntity; +import io.renren.modules.sys.service.SysMenuService; +import io.renren.modules.sys.service.SysRoleMenuService; +import io.renren.modules.sys.service.SysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + + +@Service("sysMenuService") +public class SysMenuServiceImpl extends ServiceImpl implements SysMenuService { + @Autowired + private SysUserService sysUserService; + @Autowired + private SysRoleMenuService sysRoleMenuService; + + @Override + public List queryListParentId(Long parentId, List menuIdList) { + List menuList = queryListParentId(parentId); + if(menuIdList == null){ + return menuList; + } + + List userMenuList = new ArrayList<>(); + for(SysMenuEntity menu : menuList){ + if(menuIdList.contains(menu.getMenuId())){ + userMenuList.add(menu); + } + } + return userMenuList; + } + + @Override + public List queryListParentId(Long parentId) { + return baseMapper.queryListParentId(parentId); + } + + @Override + public List queryNotButtonList() { + return baseMapper.queryNotButtonList(); + } + + @Override + public List getUserMenuList(Long userId) { + //系统管理员,拥有最高权限 + if(userId == Constant.SUPER_ADMIN){ + return getMenuList(null); + } + + //用户菜单列表 + List menuIdList = sysUserService.queryAllMenuId(userId); + return getMenuList(menuIdList); + } + + /** + * 获取拥有的菜单列表 + * @param menuIdList + * @return + */ + private List getMenuList(List menuIdList) { + // 查询拥有的所有菜单 + List menus = this.baseMapper.selectList(new QueryWrapper() + .in(Objects.nonNull(menuIdList), "menu_id", menuIdList).in("type", 0, 1)); + //查询完成 对此list直接排序 + Collections.sort(menus); + + // 将id和菜单绑定 + HashMap menuMap = new HashMap<>(12); + for (SysMenuEntity s : menus) { + menuMap.put(s.getMenuId(), s); + } + // 使用迭代器,组装菜单的层级关系 + Iterator iterator = menus.iterator(); + while (iterator.hasNext()) { + SysMenuEntity menu = iterator.next(); + SysMenuEntity parent = menuMap.get(menu.getParentId()); + if (Objects.nonNull(parent)) { + parent.getList().add(menu); + // 将这个菜单从当前节点移除 + iterator.remove(); + } + } + + return menus; + } + + @Override + public void delete(Long menuId){ + //删除菜单 + this.removeById(menuId); + //删除菜单与角色关联 + sysRoleMenuService.removeByMap(new MapUtils().put("menu_id", menuId)); + } + + /** + * 获取所有菜单列表 + */ + private List getAllMenuList(List menuIdList){ + //查询根菜单列表 + List menuList = queryListParentId(0L, menuIdList); + //递归获取子菜单 + getMenuTreeList(menuList, menuIdList); + + return menuList; + } + + /** + * 递归 + */ + private List getMenuTreeList(List menuList, List menuIdList){ + List subMenuList = new ArrayList(); + + for(SysMenuEntity entity : menuList){ + //目录 + if(entity.getType() == Constant.MenuType.CATALOG.getValue()){ + entity.setList(getMenuTreeList(queryListParentId(entity.getMenuId(), menuIdList), menuIdList)); + } + subMenuList.add(entity); + } + + return subMenuList; + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java new file mode 100644 index 0000000..1d86268 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleMenuServiceImpl.java @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +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("sysRoleMenuService") +public class SysRoleMenuServiceImpl extends ServiceImpl implements SysRoleMenuService { + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveOrUpdate(Long roleId, List menuIdList) { + //先删除角色与菜单关系 + deleteBatch(new Long[]{roleId}); + + if(menuIdList.size() == 0){ + return ; + } + + //保存角色与菜单关系 + for(Long menuId : menuIdList){ + SysRoleMenuEntity sysRoleMenuEntity = new SysRoleMenuEntity(); + sysRoleMenuEntity.setMenuId(menuId); + sysRoleMenuEntity.setRoleId(roleId); + + this.save(sysRoleMenuEntity); + } + } + + @Override + public List queryMenuIdList(Long roleId) { + return baseMapper.queryMenuIdList(roleId); + } + + @Override + public int deleteBatch(Long[] roleIds){ + return baseMapper.deleteBatch(roleIds); + } + +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..4885831 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.exception.RRException; +import io.renren.common.utils.Constant; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.Query; +import io.renren.modules.sys.dao.SysRoleDao; +import io.renren.modules.sys.dao.SysUserDao; +import io.renren.modules.sys.entity.SysRoleEntity; +import io.renren.modules.sys.service.SysRoleMenuService; +import io.renren.modules.sys.service.SysRoleService; +import io.renren.modules.sys.service.SysUserRoleService; +import org.apache.commons.lang.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.Date; +import java.util.List; +import java.util.Map; + +/** + * 角色 + * + * @author Mark sunlightcs@gmail.com + */ +@Service("sysRoleService") +public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService { + @Autowired + private SysRoleMenuService sysRoleMenuService; + @Autowired + private SysUserDao sysUserDao; + @Autowired + private SysUserRoleService sysUserRoleService; + + @Override + public PageUtils queryPage(Map params) { + String roleName = (String)params.get("roleName"); + Long createUserId = (Long)params.get("createUserId"); + + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + .like(StringUtils.isNotBlank(roleName),"role_name", roleName) + .eq(createUserId != null,"create_user_id", createUserId) + ); + + return new PageUtils(page); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveRole(SysRoleEntity role) { + role.setCreateTime(new Date()); + this.save(role); + + //检查权限是否越权 + checkPrems(role); + + //保存角色与菜单关系 + sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SysRoleEntity role) { + this.updateById(role); + + //检查权限是否越权 + checkPrems(role); + + //更新角色与菜单关系 + sysRoleMenuService.saveOrUpdate(role.getRoleId(), role.getMenuIdList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteBatch(Long[] roleIds) { + //删除角色 + this.removeByIds(Arrays.asList(roleIds)); + + //删除角色与菜单关联 + sysRoleMenuService.deleteBatch(roleIds); + + //删除角色与用户关联 + sysUserRoleService.deleteBatch(roleIds); + } + + + @Override + public List queryRoleIdList(Long createUserId) { + return baseMapper.queryRoleIdList(createUserId); + } + + /** + * 检查权限是否越权 + */ + private void checkPrems(SysRoleEntity role){ + //如果不是超级管理员,则需要判断角色的权限是否超过自己的权限 + if(role.getCreateUserId() == Constant.SUPER_ADMIN){ + return ; + } + + //查询用户所拥有的菜单列表 + List menuIdList = sysUserDao.queryAllMenuId(role.getCreateUserId()); + + //判断是否越权 + if(!menuIdList.containsAll(role.getMenuIdList())){ + throw new RRException("新增角色的权限,已超出你的权限范围"); + } + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserRoleServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserRoleServiceImpl.java new file mode 100644 index 0000000..7235c18 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserRoleServiceImpl.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.utils.MapUtils; +import io.renren.modules.sys.dao.SysUserRoleDao; +import io.renren.modules.sys.entity.SysUserRoleEntity; +import io.renren.modules.sys.service.SysUserRoleService; +import org.springframework.stereotype.Service; + +import java.util.List; + + + +/** + * 用户与角色对应关系 + * + * @author Mark sunlightcs@gmail.com + */ +@Service("sysUserRoleService") +public class SysUserRoleServiceImpl extends ServiceImpl implements SysUserRoleService { + + @Override + public void saveOrUpdate(Long userId, List roleIdList) { + //先删除用户与角色关系 + this.removeByMap(new MapUtils().put("user_id", userId)); + + if(roleIdList == null || roleIdList.size() == 0){ + return ; + } + + //保存用户与角色关系 + for(Long roleId : roleIdList){ + SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity(); + sysUserRoleEntity.setUserId(userId); + sysUserRoleEntity.setRoleId(roleId); + + this.save(sysUserRoleEntity); + } + } + + @Override + public List queryRoleIdList(Long userId) { + return baseMapper.queryRoleIdList(userId); + } + + @Override + public int deleteBatch(Long[] roleIds){ + return baseMapper.deleteBatch(roleIds); + } +} diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..52b8290 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2016-2019 人人开源 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.exception.RRException; +import io.renren.common.utils.Constant; +import io.renren.common.utils.PageUtils; +import io.renren.common.utils.Query; +import io.renren.modules.sys.dao.SysUserDao; +import io.renren.modules.sys.entity.SysUserEntity; +import io.renren.modules.sys.service.SysRoleService; +import io.renren.modules.sys.service.SysUserRoleService; +import io.renren.modules.sys.service.SysUserService; +import org.apache.commons.lang.RandomStringUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.shiro.crypto.hash.Sha256Hash; +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.Date; +import java.util.List; +import java.util.Map; + + +/** + * 系统用户 + * + * @author Mark sunlightcs@gmail.com + */ +@Service("sysUserService") +public class SysUserServiceImpl extends ServiceImpl implements SysUserService { + @Autowired + private SysUserRoleService sysUserRoleService; + @Autowired + private SysRoleService sysRoleService; + + @Override + public PageUtils queryPage(Map params) { + String username = (String)params.get("username"); + Long createUserId = (Long)params.get("createUserId"); + + IPage page = this.page( + new Query().getPage(params), + new QueryWrapper() + .like(StringUtils.isNotBlank(username),"username", username) + .eq(createUserId != null,"create_user_id", createUserId) + ); + + return new PageUtils(page); + } + + @Override + public List queryAllPerms(Long userId) { + return baseMapper.queryAllPerms(userId); + } + + @Override + public List queryAllMenuId(Long userId) { + return baseMapper.queryAllMenuId(userId); + } + + @Override + public SysUserEntity queryByUserName(String username) { + return baseMapper.queryByUserName(username); + } + + @Override + @Transactional + public void saveUser(SysUserEntity user) { + user.setCreateTime(new Date()); + //sha256加密 + String salt = RandomStringUtils.randomAlphanumeric(20); + user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex()); + user.setSalt(salt); + this.save(user); + + //检查角色是否越权 + checkRole(user); + + //保存用户与角色关系 + sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList()); + } + + @Override + @Transactional + public void update(SysUserEntity user) { + if(StringUtils.isBlank(user.getPassword())){ + user.setPassword(null); + }else{ + user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex()); + } + this.updateById(user); + + //检查角色是否越权 + checkRole(user); + + //保存用户与角色关系 + sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList()); + } + + @Override + public void deleteBatch(Long[] userId) { + this.removeByIds(Arrays.asList(userId)); + } + + @Override + public boolean updatePassword(Long userId, String password, String newPassword) { + SysUserEntity userEntity = new SysUserEntity(); + userEntity.setPassword(newPassword); + return this.update(userEntity, + new QueryWrapper().eq("user_id", userId).eq("password", password)); + } + + /** + * 检查角色是否越权 + */ + private void checkRole(SysUserEntity user){ + if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){ + return; + } + //如果不是超级管理员,则需要判断用户的角色是否自己创建 + if(user.getCreateUserId() == Constant.SUPER_ADMIN){ + return ; + } + + //查询用户创建的角色列表 + List roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId()); + + //判断是否越权 + if(!roleIdList.containsAll(user.getRoleIdList())){ + throw new RRException("新增用户所选角色,不是本人创建"); + } + } +} \ No newline at end of file diff --git a/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserTokenServiceImpl.java b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserTokenServiceImpl.java new file mode 100644 index 0000000..15d2575 --- /dev/null +++ b/renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserTokenServiceImpl.java @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package io.renren.modules.sys.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.renren.common.utils.R; +import io.renren.modules.sys.dao.SysUserTokenDao; +import io.renren.modules.sys.entity.SysUserTokenEntity; +import io.renren.modules.sys.jwt.TokenGenerator; +import io.renren.modules.sys.service.SysUserTokenService; +import org.springframework.stereotype.Service; + +import java.util.Date; + + +@Service("sysUserTokenService") +public class SysUserTokenServiceImpl extends ServiceImpl implements SysUserTokenService { + //12小时后过期 + private final static int EXPIRE = 3600 * 12; + + + @Override + public R createToken(long userId) { + //生成一个token + String token = TokenGenerator.generateValue(); + + //当前时间 + Date now = new Date(); + //过期时间 + Date expireTime = new Date(now.getTime() + EXPIRE * 1000); + + //判断是否生成过token + SysUserTokenEntity tokenEntity = this.getById(userId); + if(tokenEntity == null){ + tokenEntity = new SysUserTokenEntity(); + tokenEntity.setUserId(userId); + tokenEntity.setToken(token); + tokenEntity.setUpdateTime(now); + tokenEntity.setExpireTime(expireTime); + + //保存token + this.save(tokenEntity); + }else{ + tokenEntity.setToken(token); + tokenEntity.setUpdateTime(now); + tokenEntity.setExpireTime(expireTime); + + //更新token + this.updateById(tokenEntity); + } + + R r = R.ok().put("token", token).put("expire", EXPIRE); + + return r; + } + + @Override + public void logout(long userId) { + //生成一个token + String token = TokenGenerator.generateValue(); + + //修改token + SysUserTokenEntity tokenEntity = new SysUserTokenEntity(); + tokenEntity.setUserId(userId); + tokenEntity.setToken(token); + this.updateById(tokenEntity); + } +} diff --git a/renren-fast/src/main/resources/application-dev.yml b/renren-fast/src/main/resources/application-dev.yml new file mode 100644 index 0000000..399395d --- /dev/null +++ b/renren-fast/src/main/resources/application-dev.yml @@ -0,0 +1,63 @@ +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.88.131:3306/mall-admit?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai + username: root + password: 7536981 + 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 + + +##多数据源的配置 +#dynamic: +# datasource: +# slave1: +# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver +# url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security +# username: sa +# password: 123456 +# slave2: +# driver-class-name: org.postgresql.Driver +# url: jdbc:postgresql://localhost:5432/renren_security +# username: renren +# password: 123456 + + redis: + open: false # 是否开启redis缓存 true开启 false关闭 + database: 0 + host: localhost + port: 6379 + password: # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 \ No newline at end of file diff --git a/renren-fast/src/main/resources/application-prod.yml b/renren-fast/src/main/resources/application-prod.yml new file mode 100644 index 0000000..843c22f --- /dev/null +++ b/renren-fast/src/main/resources/application-prod.yml @@ -0,0 +1,63 @@ +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/renren_fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai + 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 + + +##多数据源的配置 +#dynamic: +# datasource: +# slave1: +# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver +# url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security +# username: sa +# password: 123456 +# slave2: +# driver-class-name: org.postgresql.Driver +# url: jdbc:postgresql://localhost:5432/renren_security +# username: renren +# password: 123456 + + redis: + open: false # 是否开启redis缓存 true开启 false关闭 + database: 0 + host: localhost + port: 6379 + password: # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 \ No newline at end of file diff --git a/renren-fast/src/main/resources/application-test.yml b/renren-fast/src/main/resources/application-test.yml new file mode 100644 index 0000000..843c22f --- /dev/null +++ b/renren-fast/src/main/resources/application-test.yml @@ -0,0 +1,63 @@ +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/renren_fast?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai + 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 + + +##多数据源的配置 +#dynamic: +# datasource: +# slave1: +# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver +# url: jdbc:sqlserver://localhost:1433;DatabaseName=renren_security +# username: sa +# password: 123456 +# slave2: +# driver-class-name: org.postgresql.Driver +# url: jdbc:postgresql://localhost:5432/renren_security +# username: renren +# password: 123456 + + redis: + open: false # 是否开启redis缓存 true开启 false关闭 + database: 0 + host: localhost + port: 6379 + password: # 密码(默认为空) + timeout: 6000ms # 连接超时时长(毫秒) + jedis: + pool: + max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) + max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-idle: 10 # 连接池中的最大空闲连接 + min-idle: 5 # 连接池中的最小空闲连接 \ No newline at end of file diff --git a/renren-fast/src/main/resources/application.yml b/renren-fast/src/main/resources/application.yml new file mode 100644 index 0000000..5798856 --- /dev/null +++ b/renren-fast/src/main/resources/application.yml @@ -0,0 +1,67 @@ +# Tomcat +server: + tomcat: + uri-encoding: UTF-8 + threads: + max: 1000 + min-spare: 30 + connection-timeout: 5000ms + port: 8080 + servlet: + context-path: /renren-fast + +spring: + # 环境 dev|test|prod + profiles: + active: dev + # jackson时间格式化 + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + enabled: true + + mvc: + throw-exception-if-no-handler-found: true + pathmatch: + matching-strategy: ANT_PATH_MATCHER +# resources: +# add-mappings: false + + +#mybatis +mybatis-plus: + mapper-locations: classpath*:/mapper/**/*.xml + #实体扫描,多个package用逗号或者分号分隔 + typeAliasesPackage: io.renren.modules.*.entity + global-config: + #数据库相关配置 + db-config: + #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID"; + id-type: AUTO + logic-delete-value: -1 + logic-not-delete-value: 0 + banner: false + #原生配置 + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + + +renren: + redis: + open: false + shiro: + redis: false + # APP模块,是通过jwt认证的,如果要使用APP模块,则需要修改【加密秘钥】 + jwt: + # 加密秘钥 + secret: f4e2e52034348f86b67cde581c0f9eb5[www.renren.io] + # token有效时长,7天,单位秒 + expire: 604800 + header: token \ No newline at end of file diff --git a/renren-fast/src/main/resources/banner.txt b/renren-fast/src/main/resources/banner.txt new file mode 100644 index 0000000..ec3d43f --- /dev/null +++ b/renren-fast/src/main/resources/banner.txt @@ -0,0 +1,5 @@ +==================================================================================================================== + + 欢迎使用 renren-fast 人人快速开发平台 - Powered By https://www.renren.io/ + +==================================================================================================================== \ No newline at end of file diff --git a/renren-fast/src/main/resources/logback-spring.xml b/renren-fast/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..5deef21 --- /dev/null +++ b/renren-fast/src/main/resources/logback-spring.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/app/UserDao.xml b/renren-fast/src/main/resources/mapper/app/UserDao.xml new file mode 100644 index 0000000..ba7cca9 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/app/UserDao.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/job/ScheduleJobDao.xml b/renren-fast/src/main/resources/mapper/job/ScheduleJobDao.xml new file mode 100644 index 0000000..bcfe54a --- /dev/null +++ b/renren-fast/src/main/resources/mapper/job/ScheduleJobDao.xml @@ -0,0 +1,14 @@ + + + + + + + + update schedule_job set status = #{status} where job_id in + + #{jobId} + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/job/ScheduleJobLogDao.xml b/renren-fast/src/main/resources/mapper/job/ScheduleJobLogDao.xml new file mode 100644 index 0000000..82cc799 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/job/ScheduleJobLogDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/oss/SysOssDao.xml b/renren-fast/src/main/resources/mapper/oss/SysOssDao.xml new file mode 100644 index 0000000..bbb3af4 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/oss/SysOssDao.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysConfigDao.xml b/renren-fast/src/main/resources/mapper/sys/SysConfigDao.xml new file mode 100644 index 0000000..710e866 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysConfigDao.xml @@ -0,0 +1,15 @@ + + + + + + + update sys_config set param_value = #{paramValue} where param_key = #{paramKey} + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysLogDao.xml b/renren-fast/src/main/resources/mapper/sys/SysLogDao.xml new file mode 100644 index 0000000..d2be2f9 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysLogDao.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysMenuDao.xml b/renren-fast/src/main/resources/mapper/sys/SysMenuDao.xml new file mode 100644 index 0000000..01d2370 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysMenuDao.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysRoleDao.xml b/renren-fast/src/main/resources/mapper/sys/SysRoleDao.xml new file mode 100644 index 0000000..b048b8b --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysRoleDao.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysRoleMenuDao.xml b/renren-fast/src/main/resources/mapper/sys/SysRoleMenuDao.xml new file mode 100644 index 0000000..e9453db --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysRoleMenuDao.xml @@ -0,0 +1,17 @@ + + + + + + + + + delete from sys_role_menu where role_id in + + #{roleId} + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysUserDao.xml b/renren-fast/src/main/resources/mapper/sys/SysUserDao.xml new file mode 100644 index 0000000..b3e8a99 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysUserDao.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysUserRoleDao.xml b/renren-fast/src/main/resources/mapper/sys/SysUserRoleDao.xml new file mode 100644 index 0000000..e88a418 --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysUserRoleDao.xml @@ -0,0 +1,16 @@ + + + + + + + delete from sys_user_role where role_id in + + #{roleId} + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/mapper/sys/SysUserTokenDao.xml b/renren-fast/src/main/resources/mapper/sys/SysUserTokenDao.xml new file mode 100644 index 0000000..270792b --- /dev/null +++ b/renren-fast/src/main/resources/mapper/sys/SysUserTokenDao.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/renren-fast/src/main/resources/static/favicon.ico b/renren-fast/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-fast/src/main/resources/static/swagger/css/print.css b/renren-fast/src/main/resources/static/swagger/css/print.css new file mode 100644 index 0000000..f2e8446 --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/css/print.css @@ -0,0 +1 @@ +.swagger-section pre code{display:block;padding:.5em;background:#f0f0f0}.swagger-section pre .clojure .built_in,.swagger-section pre .lisp .title,.swagger-section pre .nginx .title,.swagger-section pre .subst,.swagger-section pre .tag .title,.swagger-section pre code{color:#000}.swagger-section pre .addition,.swagger-section pre .aggregate,.swagger-section pre .apache .cbracket,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .constant,.swagger-section pre .django .variable,.swagger-section pre .erlang_repl .function_or_atom,.swagger-section pre .flow,.swagger-section pre .markdown .header,.swagger-section pre .parent,.swagger-section pre .preprocessor,.swagger-section pre .ruby .symbol,.swagger-section pre .ruby .symbol .string,.swagger-section pre .rules .value,.swagger-section pre .rules .value .number,.swagger-section pre .smalltalk .class,.swagger-section pre .stream,.swagger-section pre .string,.swagger-section pre .tag .value,.swagger-section pre .template_tag,.swagger-section pre .tex .command,.swagger-section pre .tex .special,.swagger-section pre .title{color:#800}.swagger-section pre .annotation,.swagger-section pre .chunk,.swagger-section pre .comment,.swagger-section pre .diff .header,.swagger-section pre .markdown .blockquote,.swagger-section pre .template_comment{color:#888}.swagger-section pre .change,.swagger-section pre .date,.swagger-section pre .go .constant,.swagger-section pre .literal,.swagger-section pre .markdown .bullet,.swagger-section pre .markdown .link_url,.swagger-section pre .number,.swagger-section pre .regexp,.swagger-section pre .smalltalk .char,.swagger-section pre .smalltalk .symbol{color:#080}.swagger-section pre .apache .sqbracket,.swagger-section pre .array,.swagger-section pre .attr_selector,.swagger-section pre .clojure .attribute,.swagger-section pre .coffeescript .property,.swagger-section pre .decorator,.swagger-section pre .deletion,.swagger-section pre .doctype,.swagger-section pre .envvar,.swagger-section pre .erlang_repl .reserved,.swagger-section pre .filter .argument,.swagger-section pre .important,.swagger-section pre .javadoc,.swagger-section pre .label,.swagger-section pre .localvars,.swagger-section pre .markdown .link_label,.swagger-section pre .nginx .built_in,.swagger-section pre .pi,.swagger-section pre .prompt,.swagger-section pre .pseudo,.swagger-section pre .ruby .string,.swagger-section pre .shebang,.swagger-section pre .tex .formula,.swagger-section pre .vhdl .attribute{color:#88f}.swagger-section pre .aggregate,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .built_in,.swagger-section pre .css .tag,.swagger-section pre .go .typename,.swagger-section pre .id,.swagger-section pre .javadoctag,.swagger-section pre .keyword,.swagger-section pre .markdown .strong,.swagger-section pre .phpdoc,.swagger-section pre .request,.swagger-section pre .smalltalk .class,.swagger-section pre .status,.swagger-section pre .tex .command,.swagger-section pre .title,.swagger-section pre .winutils,.swagger-section pre .yardoctag{font-weight:700}.swagger-section pre .markdown .emphasis{font-style:italic}.swagger-section pre .nginx .built_in{font-weight:400}.swagger-section pre .coffeescript .javascript,.swagger-section pre .javascript .xml,.swagger-section pre .tex .formula,.swagger-section pre .xml .cdata,.swagger-section pre .xml .css,.swagger-section pre .xml .javascript,.swagger-section pre .xml .vbscript{opacity:.5}.swagger-section .hljs{display:block;overflow-x:auto;padding:.5em;background:#f0f0f0}.swagger-section .hljs,.swagger-section .hljs-subst{color:#444}.swagger-section .hljs-attribute,.swagger-section .hljs-doctag,.swagger-section .hljs-keyword,.swagger-section .hljs-meta-keyword,.swagger-section .hljs-name,.swagger-section .hljs-selector-tag{font-weight:700}.swagger-section .hljs-addition,.swagger-section .hljs-built_in,.swagger-section .hljs-bullet,.swagger-section .hljs-code,.swagger-section .hljs-literal{color:#1f811f}.swagger-section .hljs-link,.swagger-section .hljs-regexp,.swagger-section .hljs-selector-attr,.swagger-section .hljs-selector-pseudo,.swagger-section .hljs-symbol,.swagger-section .hljs-template-variable,.swagger-section .hljs-variable{color:#bc6060}.swagger-section .hljs-deletion,.swagger-section .hljs-number,.swagger-section .hljs-quote,.swagger-section .hljs-selector-class,.swagger-section .hljs-selector-id,.swagger-section .hljs-string,.swagger-section .hljs-template-tag,.swagger-section .hljs-type{color:#800}.swagger-section .hljs-section,.swagger-section .hljs-title{color:#800;font-weight:700}.swagger-section .hljs-comment{color:#888}.swagger-section .hljs-meta{color:#2b6ea1}.swagger-section .hljs-emphasis{font-style:italic}.swagger-section .hljs-strong{font-weight:700}.swagger-section .swagger-ui-wrap{line-height:1;font-family:Droid Sans,sans-serif;min-width:760px;max-width:960px;margin-left:auto;margin-right:auto}.swagger-section .swagger-ui-wrap b,.swagger-section .swagger-ui-wrap strong{font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap blockquote,.swagger-section .swagger-ui-wrap q{quotes:none}.swagger-section .swagger-ui-wrap p{line-height:1.4em;padding:0 0 10px;color:#333}.swagger-section .swagger-ui-wrap blockquote:after,.swagger-section .swagger-ui-wrap blockquote:before,.swagger-section .swagger-ui-wrap q:after,.swagger-section .swagger-ui-wrap q:before{content:none}.swagger-section .swagger-ui-wrap .heading_with_menu h1,.swagger-section .swagger-ui-wrap .heading_with_menu h2,.swagger-section .swagger-ui-wrap .heading_with_menu h3,.swagger-section .swagger-ui-wrap .heading_with_menu h4,.swagger-section .swagger-ui-wrap .heading_with_menu h5,.swagger-section .swagger-ui-wrap .heading_with_menu h6{display:block;clear:none;float:left;-ms-box-sizing:border-box;box-sizing:border-box;width:60%}.swagger-section .swagger-ui-wrap table{border-collapse:collapse;border-spacing:0}.swagger-section .swagger-ui-wrap table thead tr th{padding:5px;font-size:.9em;color:#666;border-bottom:1px solid #999}.swagger-section .swagger-ui-wrap table tbody tr:last-child td{border-bottom:none}.swagger-section .swagger-ui-wrap table tbody tr.offset{background-color:#f0f0f0}.swagger-section .swagger-ui-wrap table tbody tr td{padding:6px;font-size:.9em;border-bottom:1px solid #ccc;vertical-align:top;line-height:1.3em}.swagger-section .swagger-ui-wrap ol{margin:0 0 10px;padding:0 0 0 18px;list-style-type:decimal}.swagger-section .swagger-ui-wrap ol li{padding:5px 0;font-size:.9em;color:#333}.swagger-section .swagger-ui-wrap ol,.swagger-section .swagger-ui-wrap ul{list-style:none}.swagger-section .swagger-ui-wrap h1 a,.swagger-section .swagger-ui-wrap h2 a,.swagger-section .swagger-ui-wrap h3 a,.swagger-section .swagger-ui-wrap h4 a,.swagger-section .swagger-ui-wrap h5 a,.swagger-section .swagger-ui-wrap h6 a{text-decoration:none}.swagger-section .swagger-ui-wrap h1 a:hover,.swagger-section .swagger-ui-wrap h2 a:hover,.swagger-section .swagger-ui-wrap h3 a:hover,.swagger-section .swagger-ui-wrap h4 a:hover,.swagger-section .swagger-ui-wrap h5 a:hover,.swagger-section .swagger-ui-wrap h6 a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap h1 span.divider,.swagger-section .swagger-ui-wrap h2 span.divider,.swagger-section .swagger-ui-wrap h3 span.divider,.swagger-section .swagger-ui-wrap h4 span.divider,.swagger-section .swagger-ui-wrap h5 span.divider,.swagger-section .swagger-ui-wrap h6 span.divider{color:#aaa}.swagger-section .swagger-ui-wrap a{color:#547f00}.swagger-section .swagger-ui-wrap a img{border:none}.swagger-section .swagger-ui-wrap article,.swagger-section .swagger-ui-wrap aside,.swagger-section .swagger-ui-wrap details,.swagger-section .swagger-ui-wrap figcaption,.swagger-section .swagger-ui-wrap figure,.swagger-section .swagger-ui-wrap footer,.swagger-section .swagger-ui-wrap header,.swagger-section .swagger-ui-wrap hgroup,.swagger-section .swagger-ui-wrap menu,.swagger-section .swagger-ui-wrap nav,.swagger-section .swagger-ui-wrap section,.swagger-section .swagger-ui-wrap summary{display:block}.swagger-section .swagger-ui-wrap pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px}.swagger-section .swagger-ui-wrap pre code{line-height:1.6em;background:none}.swagger-section .swagger-ui-wrap .content>.content-type>div>label{clear:both;display:block;color:#0f6ab4;font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap .content pre{font-size:12px;margin-top:5px;padding:5px}.swagger-section .swagger-ui-wrap .icon-btn{cursor:pointer}.swagger-section .swagger-ui-wrap .info_title{padding-bottom:10px;font-weight:700;font-size:25px}.swagger-section .swagger-ui-wrap .footer{margin-top:20px}.swagger-section .swagger-ui-wrap div.big p,.swagger-section .swagger-ui-wrap p.big{font-size:1em;margin-bottom:10px}.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input{width:500px!important}.swagger-section .swagger-ui-wrap .info_license,.swagger-section .swagger-ui-wrap .info_tos{padding-bottom:5px}.swagger-section .swagger-ui-wrap .message-fail{color:#c00}.swagger-section .swagger-ui-wrap .info_email,.swagger-section .swagger-ui-wrap .info_name,.swagger-section .swagger-ui-wrap .info_url{padding-bottom:5px}.swagger-section .swagger-ui-wrap .info_description{padding-bottom:10px;font-size:15px}.swagger-section .swagger-ui-wrap .markdown ol li,.swagger-section .swagger-ui-wrap .markdown ul li{padding:3px 0;line-height:1.4em;color:#333}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input{display:block;padding:4px;width:auto;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title{font-size:1.3em}.swagger-section .swagger-ui-wrap table.fullwidth{width:100%}.swagger-section .swagger-ui-wrap .model-signature{font-family:Droid Sans,sans-serif;font-size:1em;line-height:1.5em}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a{text-decoration:none;color:#aaa}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap .model-signature .propType{color:#55a}.swagger-section .swagger-ui-wrap .model-signature pre:hover{background-color:#ffd}.swagger-section .swagger-ui-wrap .model-signature pre{font-size:.85em;line-height:1.2em;overflow:auto;height:200px;resize:vertical;cursor:pointer}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav{display:block;min-width:230px;margin:0;padding:0}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li{float:left;margin:0 5px 5px 0;padding:2px 5px 2px 0;border-right:1px solid #ddd}.swagger-section .swagger-ui-wrap .model-signature .propOpt{color:#555}.swagger-section .swagger-ui-wrap .model-signature .snippet small{font-size:.75em}.swagger-section .swagger-ui-wrap .model-signature .propOptKey{font-style:italic}.swagger-section .swagger-ui-wrap .model-signature .description .strong{font-weight:700;color:#000;font-size:.9em}.swagger-section .swagger-ui-wrap .model-signature .description div{font-size:.9em;line-height:1.5em;margin-left:1em}.swagger-section .swagger-ui-wrap .model-signature .description .stronger{font-weight:700;color:#000}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper{border-spacing:0;position:absolute;background-color:#fff;border:1px solid #bbb;display:none;font-size:11px;max-width:400px;line-height:30px;color:#000;padding:5px;margin-left:10px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th{text-align:center;background-color:#eee;border:1px solid #bbb;font-size:11px;color:#666;font-weight:700;padding:5px;line-height:15px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:first-child,.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:last-child{display:inline}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:not(:first-child):before{display:block;content:''}.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown>p:only-child{margin-right:-3px}.swagger-section .swagger-ui-wrap .model-signature .propName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .signature-container{clear:both}.swagger-section .swagger-ui-wrap .body-textarea{width:300px;height:100px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap .markdown li code,.swagger-section .swagger-ui-wrap .markdown p code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#f0f0f0;color:#000;padding:1px 3px}.swagger-section .swagger-ui-wrap .required{font-weight:700}.swagger-section .swagger-ui-wrap .editor_holder{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em}.swagger-section .swagger-ui-wrap .editor_holder label{font-weight:400!important}.swagger-section .swagger-ui-wrap .editor_holder label.required{font-weight:700!important}.swagger-section .swagger-ui-wrap input.parameter{width:300px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap h1{color:#000;font-size:1.5em;line-height:1.3em;padding:10px 0;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap .heading_with_menu{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap .heading_with_menu ul{display:block;clear:none;float:right;-ms-box-sizing:border-box;box-sizing:border-box;margin-top:10px}.swagger-section .swagger-ui-wrap h2{color:#000;font-size:1.3em;padding:10px 0}.swagger-section .swagger-ui-wrap h2 a{color:#000}.swagger-section .swagger-ui-wrap h2 span.sub{font-size:.7em;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap h2 span.sub a{color:#777}.swagger-section .swagger-ui-wrap span.weak{color:#666}.swagger-section .swagger-ui-wrap .message-success{color:#89bf04}.swagger-section .swagger-ui-wrap caption,.swagger-section .swagger-ui-wrap td,.swagger-section .swagger-ui-wrap th{text-align:left;font-weight:400;vertical-align:middle}.swagger-section .swagger-ui-wrap .code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea{font-family:Droid Sans,sans-serif;height:250px;padding:4px;display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select{display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label{display:block;float:left;clear:none;margin:0;padding:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input{display:block;float:left;clear:none;margin:0 5px 0 0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label{color:#000}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label{display:block;clear:both;width:auto;padding:0 0 3px;color:#666}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr{padding-left:3px;color:#888}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints{margin-left:0;font-style:italic;font-size:.9em;margin:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons{margin:0;padding:0}.swagger-section .swagger-ui-wrap span.blank,.swagger-section .swagger-ui-wrap span.empty{color:#888;font-style:italic}.swagger-section .swagger-ui-wrap .markdown h3{color:#547f00}.swagger-section .swagger-ui-wrap .markdown h4{color:#666}.swagger-section .swagger-ui-wrap .markdown pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px;margin:0 0 10px}.swagger-section .swagger-ui-wrap .markdown pre code{line-height:1.6em;overflow:auto}.swagger-section .swagger-ui-wrap div.gist{margin:20px 0 25px!important}.swagger-section .swagger-ui-wrap ul#resources{font-family:Droid Sans,sans-serif;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource{border-bottom:1px solid #ddd}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a{color:#555}.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child{border-bottom:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading{border:1px solid transparent;float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:14px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;border-right:1px solid #ddd;color:#666;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a{color:#aaa;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#999;padding-left:0;display:block;clear:none;float:left;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#999}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation{float:none;clear:both;overflow:hidden;display:block;margin:0 0 10px;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading{float:none;clear:both;overflow:hidden;display:block;margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3{display:block;clear:none;float:left;width:auto;margin:0;padding:0;line-height:1.1em;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path{padding-left:10px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated{text-decoration:line-through}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a{text-transform:uppercase;text-decoration:none;color:#fff;display:inline-block;width:50px;font-size:.7em;text-align:center;padding:7px 0 4px;border-radius:2px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span{margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:6px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a{text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p{color:inherit;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .nickname{color:#aaa;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{border-top:none;padding:10px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;margin:0 0 20px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4{font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a{padding:4px 0 0 10px;display:inline-block;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit{display:block;clear:none;float:left;padding:6px 8px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber{background-image:url(../images/throbber.gif);width:128px;height:16px;display:block;clear:none;float:right}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type=text].error{outline:2px solid #000;outline-color:#c00}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name=parameterContentType]{max-width:300px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;padding:10px;font-size:.9em;max-height:400px;overflow-y:auto}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading{background-color:#f9f2e9;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a{background-color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0e0ca;color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{background-color:#faf5ee;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a{text-transform:uppercase;background-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#ffd20f;color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading{background-color:#f5e8e8;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a{text-transform:uppercase;background-color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#e8c6c7;color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content{background-color:#f7eded;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a{color:#c8787a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading{background-color:#e7f6ec;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a{background-color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3e8d1;color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content{background-color:#ebf7f0;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading{background-color:#fce9e3;border:1px solid #f5d5c3}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a{background-color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0cecb;color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content{background-color:#faf0ef;border:1px solid #f0cecb}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{border-top:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap p#colophon{margin:0 15px 40px;padding:10px 0;font-size:.8em;border-top:1px solid #ddd;font-family:Droid Sans,sans-serif;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap p#colophon a{text-decoration:none;color:#547f00}.swagger-section .swagger-ui-wrap h3{color:#000;font-size:1.1em;padding:10px 0}.swagger-section .swagger-ui-wrap .markdown ol,.swagger-section .swagger-ui-wrap .markdown ul{font-family:Droid Sans,sans-serif;margin:5px 0 10px;padding:0 0 0 18px;list-style-type:disc}.swagger-section .swagger-ui-wrap form.form_box{background-color:#ebf3f9;border:1px solid #c3d9ec;padding:10px}.swagger-section .swagger-ui-wrap form.form_box label{color:#0f6ab4!important}.swagger-section .swagger-ui-wrap form.form_box input[type=submit]{display:block;padding:10px}.swagger-section .swagger-ui-wrap form.form_box p.weak{font-size:.8em}.swagger-section .swagger-ui-wrap form.form_box p{font-size:.9em;padding:0 0 15px;color:#7e7b6d}.swagger-section .swagger-ui-wrap form.form_box p a{color:#646257}.swagger-section .swagger-ui-wrap form.form_box p strong{color:#000}.swagger-section .swagger-ui-wrap .operation-status td.markdown>p:last-child{padding-bottom:0}.swagger-section .title{font-style:bold}.swagger-section .secondary_form{display:none}.swagger-section .main_image{display:block;margin-left:auto;margin-right:auto}.swagger-section .oauth_body{margin-left:100px;margin-right:100px}.swagger-section .oauth_submit{text-align:center;display:inline-block}.swagger-section .authorize-wrapper{margin:15px 0 10px}.swagger-section .authorize-wrapper_operation{float:right}.swagger-section .authorize__btn:hover{text-decoration:underline;cursor:pointer}.swagger-section .authorize__btn_operation:hover .authorize-scopes{display:block}.swagger-section .authorize-scopes{position:absolute;margin-top:20px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .authorize-scopes .authorize__scope{text-decoration:none}.swagger-section .authorize__btn_operation{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .authorize__btn_operation_login{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .authorize__btn_operation_logout{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section #auth_container{color:#fff;display:inline-block;border:none;padding:5px;width:87px;height:13px}.swagger-section #auth_container .authorize__btn{color:#fff}.swagger-section .auth_container{padding:0 0 10px;margin-bottom:5px;border-bottom:1px solid #ccc;font-size:.9em}.swagger-section .auth_container .auth__title{color:#547f00;font-size:1.2em}.swagger-section .auth_container .basic_auth__label{display:inline-block;width:60px}.swagger-section .auth_container .auth__description{color:#999;margin-bottom:5px}.swagger-section .auth_container .auth__button{margin-top:10px;height:30px}.swagger-section .auth_container .key_auth__field{margin:5px 0}.swagger-section .auth_container .key_auth__label{display:inline-block;width:60px}.swagger-section .api-popup-dialog{position:absolute;display:none}.swagger-section .api-popup-dialog-wrapper{z-index:2;width:500px;background:#fff;padding:20px;border:1px solid #ccc;border-radius:5px;font-size:13px;color:#777;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.swagger-section .api-popup-dialog-shadow{position:fixed;top:0;left:0;width:100%;height:100%;opacity:.2;background-color:gray;z-index:1}.swagger-section .api-popup-dialog .api-popup-title{font-size:24px;padding:10px 0}.swagger-section .api-popup-dialog .error-msg{padding-left:5px;padding-bottom:5px}.swagger-section .api-popup-dialog .api-popup-content{max-height:500px;overflow-y:auto}.swagger-section .api-popup-dialog .api-popup-authbtn,.swagger-section .api-popup-dialog .api-popup-cancel{height:30px}.swagger-section .api-popup-scopes{padding:10px 20px}.swagger-section .api-popup-scopes li{padding:5px 0;line-height:20px}.swagger-section .api-popup-scopes li input{position:relative;top:2px}.swagger-section .api-popup-scopes .api-scope-desc{padding-left:20px;font-style:italic}.swagger-section .api-popup-actions{padding-top:10px}.swagger-section fieldset{padding-bottom:10px;padding-left:20px}#header{display:none}.swagger-section .swagger-ui-wrap .model-signature pre{max-height:none}.swagger-section .swagger-ui-wrap .body-textarea,.swagger-section .swagger-ui-wrap input.parameter{width:100px}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{display:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{display:block!important} \ No newline at end of file diff --git a/renren-fast/src/main/resources/static/swagger/css/reset.css b/renren-fast/src/main/resources/static/swagger/css/reset.css new file mode 100644 index 0000000..40dc830 --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/css/reset.css @@ -0,0 +1 @@ +a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0} \ No newline at end of file diff --git a/renren-fast/src/main/resources/static/swagger/css/screen.css b/renren-fast/src/main/resources/static/swagger/css/screen.css new file mode 100644 index 0000000..1f069f6 --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/css/screen.css @@ -0,0 +1 @@ +.swagger-section pre code{display:block;padding:.5em;background:#f0f0f0}.swagger-section pre .clojure .built_in,.swagger-section pre .lisp .title,.swagger-section pre .nginx .title,.swagger-section pre .subst,.swagger-section pre .tag .title,.swagger-section pre code{color:#000}.swagger-section pre .addition,.swagger-section pre .aggregate,.swagger-section pre .apache .cbracket,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .constant,.swagger-section pre .django .variable,.swagger-section pre .erlang_repl .function_or_atom,.swagger-section pre .flow,.swagger-section pre .markdown .header,.swagger-section pre .parent,.swagger-section pre .preprocessor,.swagger-section pre .ruby .symbol,.swagger-section pre .ruby .symbol .string,.swagger-section pre .rules .value,.swagger-section pre .rules .value .number,.swagger-section pre .smalltalk .class,.swagger-section pre .stream,.swagger-section pre .string,.swagger-section pre .tag .value,.swagger-section pre .template_tag,.swagger-section pre .tex .command,.swagger-section pre .tex .special,.swagger-section pre .title{color:#800}.swagger-section pre .annotation,.swagger-section pre .chunk,.swagger-section pre .comment,.swagger-section pre .diff .header,.swagger-section pre .markdown .blockquote,.swagger-section pre .template_comment{color:#888}.swagger-section pre .change,.swagger-section pre .date,.swagger-section pre .go .constant,.swagger-section pre .literal,.swagger-section pre .markdown .bullet,.swagger-section pre .markdown .link_url,.swagger-section pre .number,.swagger-section pre .regexp,.swagger-section pre .smalltalk .char,.swagger-section pre .smalltalk .symbol{color:#080}.swagger-section pre .apache .sqbracket,.swagger-section pre .array,.swagger-section pre .attr_selector,.swagger-section pre .clojure .attribute,.swagger-section pre .coffeescript .property,.swagger-section pre .decorator,.swagger-section pre .deletion,.swagger-section pre .doctype,.swagger-section pre .envvar,.swagger-section pre .erlang_repl .reserved,.swagger-section pre .filter .argument,.swagger-section pre .important,.swagger-section pre .javadoc,.swagger-section pre .label,.swagger-section pre .localvars,.swagger-section pre .markdown .link_label,.swagger-section pre .nginx .built_in,.swagger-section pre .pi,.swagger-section pre .prompt,.swagger-section pre .pseudo,.swagger-section pre .ruby .string,.swagger-section pre .shebang,.swagger-section pre .tex .formula,.swagger-section pre .vhdl .attribute{color:#88f}.swagger-section pre .aggregate,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .built_in,.swagger-section pre .css .tag,.swagger-section pre .go .typename,.swagger-section pre .id,.swagger-section pre .javadoctag,.swagger-section pre .keyword,.swagger-section pre .markdown .strong,.swagger-section pre .phpdoc,.swagger-section pre .request,.swagger-section pre .smalltalk .class,.swagger-section pre .status,.swagger-section pre .tex .command,.swagger-section pre .title,.swagger-section pre .winutils,.swagger-section pre .yardoctag{font-weight:700}.swagger-section pre .markdown .emphasis{font-style:italic}.swagger-section pre .nginx .built_in{font-weight:400}.swagger-section pre .coffeescript .javascript,.swagger-section pre .javascript .xml,.swagger-section pre .tex .formula,.swagger-section pre .xml .cdata,.swagger-section pre .xml .css,.swagger-section pre .xml .javascript,.swagger-section pre .xml .vbscript{opacity:.5}.swagger-section .hljs{display:block;overflow-x:auto;padding:.5em;background:#f0f0f0}.swagger-section .hljs,.swagger-section .hljs-subst{color:#444}.swagger-section .hljs-attribute,.swagger-section .hljs-doctag,.swagger-section .hljs-keyword,.swagger-section .hljs-meta-keyword,.swagger-section .hljs-name,.swagger-section .hljs-selector-tag{font-weight:700}.swagger-section .hljs-addition,.swagger-section .hljs-built_in,.swagger-section .hljs-bullet,.swagger-section .hljs-code,.swagger-section .hljs-literal{color:#1f811f}.swagger-section .hljs-link,.swagger-section .hljs-regexp,.swagger-section .hljs-selector-attr,.swagger-section .hljs-selector-pseudo,.swagger-section .hljs-symbol,.swagger-section .hljs-template-variable,.swagger-section .hljs-variable{color:#bc6060}.swagger-section .hljs-deletion,.swagger-section .hljs-number,.swagger-section .hljs-quote,.swagger-section .hljs-selector-class,.swagger-section .hljs-selector-id,.swagger-section .hljs-string,.swagger-section .hljs-template-tag,.swagger-section .hljs-type{color:#800}.swagger-section .hljs-section,.swagger-section .hljs-title{color:#800;font-weight:700}.swagger-section .hljs-comment{color:#888}.swagger-section .hljs-meta{color:#2b6ea1}.swagger-section .hljs-emphasis{font-style:italic}.swagger-section .hljs-strong{font-weight:700}.swagger-section .swagger-ui-wrap{line-height:1;font-family:Droid Sans,sans-serif;min-width:760px;max-width:960px;margin-left:auto;margin-right:auto}.swagger-section .swagger-ui-wrap b,.swagger-section .swagger-ui-wrap strong{font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap blockquote,.swagger-section .swagger-ui-wrap q{quotes:none}.swagger-section .swagger-ui-wrap p{line-height:1.4em;padding:0 0 10px;color:#333}.swagger-section .swagger-ui-wrap blockquote:after,.swagger-section .swagger-ui-wrap blockquote:before,.swagger-section .swagger-ui-wrap q:after,.swagger-section .swagger-ui-wrap q:before{content:none}.swagger-section .swagger-ui-wrap .heading_with_menu h1,.swagger-section .swagger-ui-wrap .heading_with_menu h2,.swagger-section .swagger-ui-wrap .heading_with_menu h3,.swagger-section .swagger-ui-wrap .heading_with_menu h4,.swagger-section .swagger-ui-wrap .heading_with_menu h5,.swagger-section .swagger-ui-wrap .heading_with_menu h6{display:block;clear:none;float:left;-ms-box-sizing:border-box;box-sizing:border-box;width:60%}.swagger-section .swagger-ui-wrap table{border-collapse:collapse;border-spacing:0}.swagger-section .swagger-ui-wrap table thead tr th{padding:5px;font-size:.9em;color:#666;border-bottom:1px solid #999}.swagger-section .swagger-ui-wrap table tbody tr:last-child td{border-bottom:none}.swagger-section .swagger-ui-wrap table tbody tr.offset{background-color:#f0f0f0}.swagger-section .swagger-ui-wrap table tbody tr td{padding:6px;font-size:.9em;border-bottom:1px solid #ccc;vertical-align:top;line-height:1.3em}.swagger-section .swagger-ui-wrap ol{margin:0 0 10px;padding:0 0 0 18px;list-style-type:decimal}.swagger-section .swagger-ui-wrap ol li{padding:5px 0;font-size:.9em;color:#333}.swagger-section .swagger-ui-wrap ol,.swagger-section .swagger-ui-wrap ul{list-style:none}.swagger-section .swagger-ui-wrap h1 a,.swagger-section .swagger-ui-wrap h2 a,.swagger-section .swagger-ui-wrap h3 a,.swagger-section .swagger-ui-wrap h4 a,.swagger-section .swagger-ui-wrap h5 a,.swagger-section .swagger-ui-wrap h6 a{text-decoration:none}.swagger-section .swagger-ui-wrap h1 a:hover,.swagger-section .swagger-ui-wrap h2 a:hover,.swagger-section .swagger-ui-wrap h3 a:hover,.swagger-section .swagger-ui-wrap h4 a:hover,.swagger-section .swagger-ui-wrap h5 a:hover,.swagger-section .swagger-ui-wrap h6 a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap h1 span.divider,.swagger-section .swagger-ui-wrap h2 span.divider,.swagger-section .swagger-ui-wrap h3 span.divider,.swagger-section .swagger-ui-wrap h4 span.divider,.swagger-section .swagger-ui-wrap h5 span.divider,.swagger-section .swagger-ui-wrap h6 span.divider{color:#aaa}.swagger-section .swagger-ui-wrap a{color:#547f00}.swagger-section .swagger-ui-wrap a img{border:none}.swagger-section .swagger-ui-wrap article,.swagger-section .swagger-ui-wrap aside,.swagger-section .swagger-ui-wrap details,.swagger-section .swagger-ui-wrap figcaption,.swagger-section .swagger-ui-wrap figure,.swagger-section .swagger-ui-wrap footer,.swagger-section .swagger-ui-wrap header,.swagger-section .swagger-ui-wrap hgroup,.swagger-section .swagger-ui-wrap menu,.swagger-section .swagger-ui-wrap nav,.swagger-section .swagger-ui-wrap section,.swagger-section .swagger-ui-wrap summary{display:block}.swagger-section .swagger-ui-wrap pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px}.swagger-section .swagger-ui-wrap pre code{line-height:1.6em;background:none}.swagger-section .swagger-ui-wrap .content>.content-type>div>label{clear:both;display:block;color:#0f6ab4;font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap .content pre{font-size:12px;margin-top:5px;padding:5px}.swagger-section .swagger-ui-wrap .icon-btn{cursor:pointer}.swagger-section .swagger-ui-wrap .info_title{padding-bottom:10px;font-weight:700;font-size:25px}.swagger-section .swagger-ui-wrap .footer{margin-top:20px}.swagger-section .swagger-ui-wrap div.big p,.swagger-section .swagger-ui-wrap p.big{font-size:1em;margin-bottom:10px}.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input{width:500px!important}.swagger-section .swagger-ui-wrap .info_license,.swagger-section .swagger-ui-wrap .info_tos{padding-bottom:5px}.swagger-section .swagger-ui-wrap .message-fail{color:#c00}.swagger-section .swagger-ui-wrap .info_email,.swagger-section .swagger-ui-wrap .info_name,.swagger-section .swagger-ui-wrap .info_url{padding-bottom:5px}.swagger-section .swagger-ui-wrap .info_description{padding-bottom:10px;font-size:15px}.swagger-section .swagger-ui-wrap .markdown ol li,.swagger-section .swagger-ui-wrap .markdown ul li{padding:3px 0;line-height:1.4em;color:#333}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input{display:block;padding:4px;width:auto;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title{font-size:1.3em}.swagger-section .swagger-ui-wrap table.fullwidth{width:100%}.swagger-section .swagger-ui-wrap .model-signature{font-family:Droid Sans,sans-serif;font-size:1em;line-height:1.5em}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a{text-decoration:none;color:#aaa}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap .model-signature .propType{color:#55a}.swagger-section .swagger-ui-wrap .model-signature pre:hover{background-color:#ffd}.swagger-section .swagger-ui-wrap .model-signature pre{font-size:.85em;line-height:1.2em;overflow:auto;height:200px;resize:vertical;cursor:pointer}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav{display:block;min-width:230px;margin:0;padding:0}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li{float:left;margin:0 5px 5px 0;padding:2px 5px 2px 0;border-right:1px solid #ddd}.swagger-section .swagger-ui-wrap .model-signature .propOpt{color:#555}.swagger-section .swagger-ui-wrap .model-signature .snippet small{font-size:.75em}.swagger-section .swagger-ui-wrap .model-signature .propOptKey{font-style:italic}.swagger-section .swagger-ui-wrap .model-signature .description .strong{font-weight:700;color:#000;font-size:.9em}.swagger-section .swagger-ui-wrap .model-signature .description div{font-size:.9em;line-height:1.5em;margin-left:1em}.swagger-section .swagger-ui-wrap .model-signature .description .stronger{font-weight:700;color:#000}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper{border-spacing:0;position:absolute;background-color:#fff;border:1px solid #bbb;display:none;font-size:11px;max-width:400px;line-height:30px;color:#000;padding:5px;margin-left:10px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th{text-align:center;background-color:#eee;border:1px solid #bbb;font-size:11px;color:#666;font-weight:700;padding:5px;line-height:15px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:first-child,.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:last-child{display:inline}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:not(:first-child):before{display:block;content:''}.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown>p:only-child{margin-right:-3px}.swagger-section .swagger-ui-wrap .model-signature .propName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .signature-container{clear:both}.swagger-section .swagger-ui-wrap .body-textarea{width:300px;height:100px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap .markdown li code,.swagger-section .swagger-ui-wrap .markdown p code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#f0f0f0;color:#000;padding:1px 3px}.swagger-section .swagger-ui-wrap .required{font-weight:700}.swagger-section .swagger-ui-wrap .editor_holder{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em}.swagger-section .swagger-ui-wrap .editor_holder label{font-weight:400!important}.swagger-section .swagger-ui-wrap .editor_holder label.required{font-weight:700!important}.swagger-section .swagger-ui-wrap input.parameter{width:300px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap h1{color:#000;font-size:1.5em;line-height:1.3em;padding:10px 0;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap .heading_with_menu{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap .heading_with_menu ul{display:block;clear:none;float:right;-ms-box-sizing:border-box;box-sizing:border-box;margin-top:10px}.swagger-section .swagger-ui-wrap h2{color:#000;font-size:1.3em;padding:10px 0}.swagger-section .swagger-ui-wrap h2 a{color:#000}.swagger-section .swagger-ui-wrap h2 span.sub{font-size:.7em;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap h2 span.sub a{color:#777}.swagger-section .swagger-ui-wrap span.weak{color:#666}.swagger-section .swagger-ui-wrap .message-success{color:#89bf04}.swagger-section .swagger-ui-wrap caption,.swagger-section .swagger-ui-wrap td,.swagger-section .swagger-ui-wrap th{text-align:left;font-weight:400;vertical-align:middle}.swagger-section .swagger-ui-wrap .code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea{font-family:Droid Sans,sans-serif;height:250px;padding:4px;display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select{display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label{display:block;float:left;clear:none;margin:0;padding:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input{display:block;float:left;clear:none;margin:0 5px 0 0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label{color:#000}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label{display:block;clear:both;width:auto;padding:0 0 3px;color:#666}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr{padding-left:3px;color:#888}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints{margin-left:0;font-style:italic;font-size:.9em;margin:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons{margin:0;padding:0}.swagger-section .swagger-ui-wrap span.blank,.swagger-section .swagger-ui-wrap span.empty{color:#888;font-style:italic}.swagger-section .swagger-ui-wrap .markdown h3{color:#547f00}.swagger-section .swagger-ui-wrap .markdown h4{color:#666}.swagger-section .swagger-ui-wrap .markdown pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px;margin:0 0 10px}.swagger-section .swagger-ui-wrap .markdown pre code{line-height:1.6em;overflow:auto}.swagger-section .swagger-ui-wrap div.gist{margin:20px 0 25px!important}.swagger-section .swagger-ui-wrap ul#resources{font-family:Droid Sans,sans-serif;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource{border-bottom:1px solid #ddd}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a{color:#555}.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child{border-bottom:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading{border:1px solid transparent;float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:14px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;border-right:1px solid #ddd;color:#666;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a{color:#aaa;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#999;padding-left:0;display:block;clear:none;float:left;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#999}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation{float:none;clear:both;overflow:hidden;display:block;margin:0 0 10px;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading{float:none;clear:both;overflow:hidden;display:block;margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3{display:block;clear:none;float:left;width:auto;margin:0;padding:0;line-height:1.1em;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path{padding-left:10px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated{text-decoration:line-through}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a{text-transform:uppercase;text-decoration:none;color:#fff;display:inline-block;width:50px;font-size:.7em;text-align:center;padding:7px 0 4px;border-radius:2px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span{margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:6px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a{text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p{color:inherit;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .nickname{color:#aaa;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{border-top:none;padding:10px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;margin:0 0 20px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4{font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a{padding:4px 0 0 10px;display:inline-block;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit{display:block;clear:none;float:left;padding:6px 8px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber{background-image:url(../images/throbber.gif);width:128px;height:16px;display:block;clear:none;float:right}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type=text].error{outline:2px solid #000;outline-color:#c00}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name=parameterContentType]{max-width:300px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;padding:10px;font-size:.9em;max-height:400px;overflow-y:auto}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading{background-color:#f9f2e9;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a{background-color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0e0ca;color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{background-color:#faf5ee;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a{text-transform:uppercase;background-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#ffd20f;color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading{background-color:#f5e8e8;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a{text-transform:uppercase;background-color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#e8c6c7;color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content{background-color:#f7eded;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a{color:#c8787a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading{background-color:#e7f6ec;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a{background-color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3e8d1;color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content{background-color:#ebf7f0;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading{background-color:#fce9e3;border:1px solid #f5d5c3}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a{background-color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0cecb;color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content{background-color:#faf0ef;border:1px solid #f0cecb}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{border-top:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap p#colophon{margin:0 15px 40px;padding:10px 0;font-size:.8em;border-top:1px solid #ddd;font-family:Droid Sans,sans-serif;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap p#colophon a{text-decoration:none;color:#547f00}.swagger-section .swagger-ui-wrap h3{color:#000;font-size:1.1em;padding:10px 0}.swagger-section .swagger-ui-wrap .markdown ol,.swagger-section .swagger-ui-wrap .markdown ul{font-family:Droid Sans,sans-serif;margin:5px 0 10px;padding:0 0 0 18px;list-style-type:disc}.swagger-section .swagger-ui-wrap form.form_box{background-color:#ebf3f9;border:1px solid #c3d9ec;padding:10px}.swagger-section .swagger-ui-wrap form.form_box label{color:#0f6ab4!important}.swagger-section .swagger-ui-wrap form.form_box input[type=submit]{display:block;padding:10px}.swagger-section .swagger-ui-wrap form.form_box p.weak{font-size:.8em}.swagger-section .swagger-ui-wrap form.form_box p{font-size:.9em;padding:0 0 15px;color:#7e7b6d}.swagger-section .swagger-ui-wrap form.form_box p a{color:#646257}.swagger-section .swagger-ui-wrap form.form_box p strong{color:#000}.swagger-section .swagger-ui-wrap .operation-status td.markdown>p:last-child{padding-bottom:0}.swagger-section .title{font-style:bold}.swagger-section .secondary_form{display:none}.swagger-section .main_image{display:block;margin-left:auto;margin-right:auto}.swagger-section .oauth_body{margin-left:100px;margin-right:100px}.swagger-section .oauth_submit{text-align:center;display:inline-block}.swagger-section .authorize-wrapper{margin:15px 0 10px}.swagger-section .authorize-wrapper_operation{float:right}.swagger-section .authorize__btn:hover{text-decoration:underline;cursor:pointer}.swagger-section .authorize__btn_operation:hover .authorize-scopes{display:block}.swagger-section .authorize-scopes{position:absolute;margin-top:20px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .authorize-scopes .authorize__scope{text-decoration:none}.swagger-section .authorize__btn_operation{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .authorize__btn_operation_login{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .authorize__btn_operation_logout{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section #auth_container{color:#fff;display:inline-block;border:none;padding:5px;width:87px;height:13px}.swagger-section #auth_container .authorize__btn{color:#fff}.swagger-section .auth_container{padding:0 0 10px;margin-bottom:5px;border-bottom:1px solid #ccc;font-size:.9em}.swagger-section .auth_container .auth__title{color:#547f00;font-size:1.2em}.swagger-section .auth_container .basic_auth__label{display:inline-block;width:60px}.swagger-section .auth_container .auth__description{color:#999;margin-bottom:5px}.swagger-section .auth_container .auth__button{margin-top:10px;height:30px}.swagger-section .auth_container .key_auth__field{margin:5px 0}.swagger-section .auth_container .key_auth__label{display:inline-block;width:60px}.swagger-section .api-popup-dialog{position:absolute;display:none}.swagger-section .api-popup-dialog-wrapper{z-index:2;width:500px;background:#fff;padding:20px;border:1px solid #ccc;border-radius:5px;font-size:13px;color:#777;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.swagger-section .api-popup-dialog-shadow{position:fixed;top:0;left:0;width:100%;height:100%;opacity:.2;background-color:gray;z-index:1}.swagger-section .api-popup-dialog .api-popup-title{font-size:24px;padding:10px 0}.swagger-section .api-popup-dialog .error-msg{padding-left:5px;padding-bottom:5px}.swagger-section .api-popup-dialog .api-popup-content{max-height:500px;overflow-y:auto}.swagger-section .api-popup-dialog .api-popup-authbtn,.swagger-section .api-popup-dialog .api-popup-cancel{height:30px}.swagger-section .api-popup-scopes{padding:10px 20px}.swagger-section .api-popup-scopes li{padding:5px 0;line-height:20px}.swagger-section .api-popup-scopes li input{position:relative;top:2px}.swagger-section .api-popup-scopes .api-scope-desc{padding-left:20px;font-style:italic}.swagger-section .api-popup-actions{padding-top:10px}.swagger-section fieldset{padding-bottom:10px;padding-left:20px}.swagger-section .access,.swagger-section .auth{float:right}.swagger-section .api-ic{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .api-ic .api_information_panel{position:relative;margin-top:20px;margin-left:-5px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .api-ic .api_information_panel p .api-msg-enabled{color:green}.swagger-section .api-ic .api_information_panel p .api-msg-disabled{color:red}.swagger-section .api-ic:hover .api_information_panel{position:absolute;display:block}.swagger-section .ic-info{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-warning{background-position:-60px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-error{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-off{background-position:-90px 0;width:58px;margin-top:-4px;cursor:pointer}.swagger-section .ic-on{background-position:-160px 0;width:58px;margin-top:-4px;cursor:pointer}.swagger-section #header{background-color:#89bf04;padding:9px 14px 19px;height:23px;min-width:775px}.swagger-section #input_baseUrl{width:400px}.swagger-section #api_selector{display:block;clear:none;float:right}.swagger-section #api_selector .input{display:inline-block;clear:none;margin:0 10px 0 0}.swagger-section #api_selector input{font-size:.9em;padding:3px;margin:0}.swagger-section #input_apiKey{width:200px}.swagger-section #auth_container .authorize__btn,.swagger-section #explore{display:block;text-decoration:none;font-weight:700;padding:6px 8px;font-size:.9em;color:#fff;background-color:#547f00;border-radius:4px}.swagger-section #auth_container .authorize__btn:hover,.swagger-section #explore:hover{background-color:#547f00}.swagger-section #header #logo{font-size:1.5em;font-weight:700;text-decoration:none;color:#fff}.swagger-section #header #logo .logo__img{display:block;float:left;margin-top:2px}.swagger-section #header #logo .logo__title{display:inline-block;padding:5px 0 0 10px}.swagger-section #content_message{margin:10px 15px;font-style:italic;color:#999}.swagger-section #message-bar{min-height:30px;text-align:center;padding-top:10px}.swagger-section .swagger-collapse:before{content:"-"}.swagger-section .swagger-expand:before{content:"+"}.swagger-section .error{outline-color:#c00;background-color:#f2dede} \ No newline at end of file diff --git a/renren-fast/src/main/resources/static/swagger/css/style.css b/renren-fast/src/main/resources/static/swagger/css/style.css new file mode 100644 index 0000000..52907e4 --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/css/style.css @@ -0,0 +1 @@ +.swagger-section #header a#logo{font-size:1.5em;font-weight:700;text-decoration:none;padding:20px 0 20px 40px}#text-head{font-size:80px;font-family:Roboto,sans-serif;color:#fff;float:right;margin-right:20%}.navbar-fixed-top .navbar-brand,.navbar-fixed-top .navbar-nav,.navbar-header{height:auto}.navbar-inverse{background-color:#000;border-color:#000}#navbar-brand{margin-left:20%}.navtext{font-size:10px}.h1,h1{font-size:60px}.navbar-default .navbar-header .navbar-brand{color:#a2dfee}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#393939;font-family:Arvo,serif;font-size:1.5em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#525252;padding-left:0;display:block;clear:none;float:left;font-family:Arvo,serif;font-weight:700}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#0a0a0a}.container1{width:1500px;margin:auto;margin-top:0;background-repeat:no-repeat;background-position:-40px -20px;margin-bottom:210px}.container-inner{width:1200px;margin:auto;background-color:hsla(192,8%,88%,.75);padding-bottom:40px;padding-top:40px;border-radius:15px}.header-content{padding:0;width:1000px}.title1{font-size:80px;font-family:Vollkorn,serif;color:#404040;text-align:center;padding-top:40px;padding-bottom:100px}#icon{margin-top:-18px}.subtext{font-size:25px;font-style:italic;color:#08b;text-align:right;padding-right:250px}.bg-primary{background-color:#00468b}.navbar-default .nav>li>a,.navbar-default .nav>li>a:focus,.navbar-default .nav>li>a:focus:hover,.navbar-default .nav>li>a:hover{color:#08b}.text-faded{font-size:25px;font-family:Vollkorn,serif}.section-heading{font-family:Vollkorn,serif;font-size:45px;padding-bottom:10px}hr{border-color:#00468b;padding-bottom:10px}.description{margin-top:20px;padding-bottom:200px}.description li{font-family:Vollkorn,serif;font-size:25px;color:#525252;margin-left:28%;padding-top:5px}.gap{margin-top:200px}.troubleshootingtext{color:hsla(0,0%,100%,.7);padding-left:30%}.troubleshootingtext li{list-style-type:circle;font-size:25px;padding-bottom:5px}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.block.response_body.json:hover{cursor:pointer}.backdrop{color:blue}#myModal{height:100%}.modal-backdrop{bottom:0;position:fixed}.curl{padding:10px;font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em;max-height:400px;margin-top:5px;overflow-y:auto;background-color:#fcf6db;border:1px solid #e5e0c6;border-radius:4px}.curl_title{font-size:1.1em;margin:0;padding:15px 0 5px;font-family:Open Sans,Helvetica Neue,Arial,sans-serif;font-weight:500;line-height:1.1}.footer{display:none}.swagger-section .swagger-ui-wrap h2{padding:0}h2{margin:0;margin-bottom:5px}.markdown p,.swagger-section .swagger-ui-wrap .code{font-size:15px;font-family:Arvo,serif}.swagger-section .swagger-ui-wrap b{font-family:Arvo,serif}#signin:hover{cursor:pointer}.dropdown-menu{padding:15px}.navbar-right .dropdown-menu{left:0;right:auto}#signinbutton{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}.navbar-default .nav>li .details{color:#000;text-transform:none;font-size:15px;font-weight:400;font-family:Open Sans,sans-serif;font-style:italic;line-height:20px;top:-2px}.navbar-default .nav>li .details:hover{color:#000}#signout{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b} \ No newline at end of file diff --git a/renren-fast/src/main/resources/static/swagger/css/typography.css b/renren-fast/src/main/resources/static/swagger/css/typography.css new file mode 100644 index 0000000..e69de29 diff --git a/renren-fast/src/main/resources/static/swagger/favicon-16x16.png b/renren-fast/src/main/resources/static/swagger/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0f7e13b0d9903d27a9129950b1dad362361504e4 GIT binary patch literal 445 zcmV;u0Yd(XP)rNm2=6wQ7&2F}_`h_PI>(9Fx!5<0%l6W{u0OQ#*rglqx3__&vD?|#%fhn*Mn&YY1i+JQHqPvZ34FR@_E%P@x zzTL;Bw#nJXWY}D7^bC>-bx{t|^|R6Oci&MKvov8Op~S=}R=h^p-=vZ0uqG@LE6tP7 n92{cY$^db6>&z__iT?Z#Z8BG|DVcT0DjiaEd>Z!7_`J}8! zKk_$1lGm$vJOY&DjT-(&VGn0;R`iN9=1aOuG`H}BlY>&R3KbGER zB2$7euhH;y1C_LTQex%L6khZpkjFn!ajOUK)f3JLz+I;CE@(N)T)CM4AWjfl-(04= zrsMQ)#NG6nr^Y7!6LA;iHXh?UOFE%hhy>7dl=;I$J>g0BH_r|_4ctEsXx z2sDIQnwa*rcK=*3XUC$D{I@}DTNs@GCb7dB2%%nV%jR){xktt;Ah09op7x@l5D6B2 z0uBdt0YmcN!o?lMpu9Io(1&B1s{TUu*a>2&>Iycx__fbDRM8PYtLt+#G*xSt(cn}K zt!~W2{`9r)xkh^xodLS&FbYw`x$t&Vhl?)#f&k-lZIs<`$gTj{^#^HewuJz(WnUZZ z{Ty_aE;^93bhc-^^k6ZM!^e~$q5!Zz`XPta{a@651gPzaFx$&%IHL6hx$mSeAa#n6 zLkyc-M zs$qhBZhCNE^aIEV)H_~^IeqSRnvo!21Qc`Z;S9!IqXl4K(RUImejotzuG65LVuGS# zcqp@OA8~ln^4c^VihUew)IOX^E9KMtvSvnZ| zC@rl{f(B*PA26aFR`|X!!I(7x_|kq{rlqwhCia+CfNbOg_yYt0bDCc4g#h#`3jpCd zNAhr%4#Ye{i>ni$fzY%r0IS%l3HHZ4tTjOi=JW-t_iG~)oC!2C!52Cc|TAPaH zJ}l%m9yPmA-4#lJea@uf$a`(1;={rL2f*8;7%icbF}e^_`X#ndU=SI0nIn8hXPXHS zSN4rbF}jl0HWx(_`q`-SRa9jP8Ab!}sThNkQ634k=qXBVM4`o{M>qrLJD ze*%D)S;wpxG$d%FcDf-6%zMqWA+gw!C1~T5+|ys$G3Ksm&x59Lyd?0l+LWSk6hc4~ z+yC>|4f;X3#cq3!)>#Mvb-^co7LMrzqWeKB$21I>tJgaGFwu6eB%&j?@d*8GAx~In zI1p-lXVKtcvY7;$TX~wjYw|QhB%q!npQES%F~%Aqz~pJB%rNu!xAj;>xZt75!VHju zfFy%B-`3;Qf<{h94~I62zcHv}D5pS-QCN`M8K1>jN9mpbrFk=5no8j!00000NkvXX Hu0mjfOavUK literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/fonts/DroidSans-Bold.ttf b/renren-fast/src/main/resources/static/swagger/fonts/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..036c4d135bf954ef3c2b15bc6493f72a01909aee GIT binary patch literal 42480 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 literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/fonts/DroidSans.ttf b/renren-fast/src/main/resources/static/swagger/fonts/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e517a0c5b9dfcdde4c4dee7569fa191b40f208bb GIT binary patch literal 41028 zcmbrn34ByVwm)8Vm)@7#`<703r_<>qourfQtYqn%y-7m$gd~up10n1L3<`=!5D@_p zP&N^jaTrIDfkv5#3{Sxgof)^sFz?NC9AQSs=Zp(8qmCl!{7>CZ0Gapuzu*7!Z@Ibm zR^6rQ)H$cl`JPi(gb_ko_`@J)O-=iZmT2&|2yIJ+(uCTo>Kdq_;k*jYowdzPZO1-e zUIgcZaMPLEwvLJ=J6CQ;=wLFbZ))=g5K`Ta5Pk~IBXgGyEdSB_$KFARZHKb`b8lPe zEV`?#0U_=qIKMiyeE!mr^X@1@qRR-0+4%z_%b^`&czy!hub98&_Mz#;iaQa~--pm} z>VkO#gI|B`JP-F~Kz;rKC{Vu2Zh>=X4@zFJbmi)$BkfR6Nub#cONQqTytw6kxL11- zu6b(d!0P4nLQL+5GUQw~uyo%0ZEMaVv;o>6-mrXlWaSettBVoZnhV!_viz2L%kTcZ zONWs1TX^PYh|mhQtjDi>(yuQ08ad!K@O#75^o_8eeQ$T{U`#JQDjtDz38F|T{NNt( zNK8+Pp#BN*QQ=APy7=GoLdkiw5V5EYXh0zj`B4wN)qy^S5x|IMQt%F_MeKey2#-vR z@9B5Z5dJ${Cl`rm2}4oLMMQncBj+r5a4LCtPI+4;f&yoi$N_D*M?8W*b0YjWsblKc zG1xf;f{_AfAv_CON_o*kbOGAP`cRNrfYyliqapS&v=qOCHc|^vD{Q4u-U{0gbTdRf z1Z5ud5Oo#lp==Ip&%zdgja*}bZ3Ap8VC#Wx5!r<6JtzdnLsJ{Q0C_}Tpryyc z^z0sVlGzI5poR8D;MoPRHN!KOqC?PT6YPUb1xlmqCayA%;mu44^)XR&ls*A%j=~m3 zE2t-so$(+KGlq^*T6B=oPMoH{6^@UJeds7DXC4!-KT7VQbKw31s0Z5Wg1STW1sJ_= z;r$4?=}(c2-URQzKnn1w~JxLF!3VMSna= zf1o`nW6;DEdZ}>z5Y*?u<`DXF79C|vq5UvE_z-eKd5C%oRlxo2?8hhsTLx?npna7< zcS8G{Hqm<%F)|ip9B$m8Z)L(*j3Eu|c^E7I)Hsl_xN(DiY!l95EXa6FZNgZT0tgS@eneRP2lxUU=JI;9))NM?V%cB9AU$<*g>GJ0z?ROrm!V| zU2)C zGXd&~NZrJrCSIP{IX*uAm+?<8K6f#C@z}*97x!G;Hu)~{zW?EeMS>y{YB14EWV`VP zEu|S&B$h~Ja)nZ*<}_NJ-e5GDEmm8CJ<;KGCApJ5Dc;nybYDhhmOncu5X{ZXFDNXU zR$NkA7UIh*Dq+T`4NtGDZT8jchlyr5AA#G$4?x3 z@+Uui`kBK=es=6=^!Rf>KQVUl`P0Anw-?bZgYy=?z4}MX7o*!2q5JkD(4+HL35{HG zCwl7C`nk)<$w; zwClj5kG%ZKYby|X^$y`Ne06tMM|)dqOLJ4>jE4HU>EYU%>Z;0$az0d6T2ef%sIVYE zFDKidm6?(1P4OhVlUxq7Uc;$XO1Vrb5sO%crZCE=cGpCl(UeG(NpXk6ndIC(00jd# z6hxvmD&3XyWSJT0 zxJ(X*ayW{nx|bivsbyF=pi--+9jA~)NnRVJJ=Ft)(dL$}>MEPd)t#9!J*slUlb{M! z3XhD6Dx+fIkJJf3l8%l#)gG$-Oy47vvgW_LyD0l0SyUA<+?rl`gjO>^H6oQY zFj8B#)VQ5BTOwNqPEL%@aXUHpmg5S=mgUtzVbt6e#ZZ1~t1Vh{e|MCNEWpzyJ6qFQ zAJw(Y>WWgH8s~xm=sx@lxm|@emj*f@5Tpj~|DUT75CX^nG2bs6L+UhdTx$FhmQC_M!|5LyesOjhI@h8tG5u|B26IAa<_E7fPxbj zkLNmV&jnE~>aK#~sIe0GDy4c$*Wggp5wQ(|qzyT{Y_2HZ4FlZm?wZ$47!4?tb`f3& zKj>DJs%-D7Z*$kT^mM_fy1IoLQb8Wac&cxDjJwMge+;l(RN|31yC@so4Ht4y;H-fI zcSQ;Ojfy=I*f=1#P)b;}qQu#SZD{IhXht;6Sv{|6@;Y+rC$!~!xQ7gP(Bnx5V76jo<6w6-PTni zTn!pzt?dr-ZY`?E_3agz8KBH6j=S-FEysC$Ut3St3miiw>N*O_ zn0Og4ly$=oM#;PY7!nkFwR4b+&z;>1wnVxKk0T>c1peVDc9#Kl+-1ixB~nCX?s*ka zxx0dthe&xSUM?c#Vs}Lp8*ygF9b33+_t)l31bySA-_jF~?f-oIpVYd4;K<+c$%+5w zeScMOH6I2)==j6L?>n+Tz#m|`drk_sNJ{+YW)v}9&CD$<{wn3Yy3O$<2&)D zd(961&gMHQnp^2ynZ1&xR^q>}#Ij*LF^r!c#(RhHt-~9Ksrq3oTZSi=;is43y~}X@ zGAy!UbB9GY;Se(u4iWS{G#@+W`{#$|Pt0fdq2{53L(w57G!Lui9h*n72L~?>QZ(sg z)1XLJGtlpIMEYwT{mn^^f6l_6&BE=o?wLhRpM{HO;qQ9zmpyoK53cXQ#XVT03u-%9 zARQB=I~+7t(;@m8O{-@*X8LE+Q{%Sd?I!a2SJz4h>d!a6xqkSSB5~ z7Il1o#pk$U(>l~@>`=d>rqt>QH6(DXuC1N;)M~#@pC-IKs?QK3^{Ymiz%ygpW zSy6mn)YC@(@-014(S1?W(KD;-IK~fjZ``&GRoLsJfwrz_#NJ&W9fSj(9E`#NXFqO4 z72P8veIqMx^-cb8|H!o;8u4LL+&_XwR>J-Vb>tjs;NFpum55vxuZC0jt%N&PLV=Im zIYKUkb2t_D2>xOp@{O#-Bjm3Sb|XF?{KG!D7x~P6B0Z9$M(}h^=vH=&eGAzCh96Uh z^awDFiO)#k^}jKF?1roU{~yM&0(1n8q0{g*@CAim2ik!4qQ}u%@bizte=FcW@;ilI zgN^(SLGAs*(K&Puu3IY{PyLCa7Z4yI@OuP33H^v$%kkPh@tyE@AzFrZpc7y!PrVtT zAv6r$$R2bCT>!3$|6+I=ym>W>fyNL}jT@dZb@&Aw>_PWIYxkhdSb_FnGx!d6w2SIN zchlspPsLkI-Hv{TPGA{AcmrAr>~~Oj#8SBT=HEj?-Q8&O^$K?E>Mo?2_!1}t;{!kN zZLim&)A%qAxDxzMqcQv+csCsF0Vn1tI~F?~8;)&2!_?1&`uLw3v>GFPimIb2I)(0} z@1;-Ee_@>F57PtvJ!r8 zUuOT$#FWI*#6u3`Xovp}IFa))E6wNl|x?`_*J~a!qohC()DddC>EAN@B{c zlv7^DTj9Oa`?B{+YDMaUsi#x_n5Ip;FYRF3$+UOV{yUvYPfdR?{mJwf(|?=(g-_yh z`U-u`zD2&beSh}FGK?8n88sP^jMp>6nUT!ZnL9EMXTF@J$a*U4OxAC+KJ!z4t3TlX zqyL+1Rd#arwCvXGMcH>}@6SGwQBF35)Uv~J(8AEF{RH14Dp@9$g&8b;L`TsmB7K==Xc0w;X=q0<=nrCl z@1@>eZIS;{PBy09vZcL0jVd<*ZeAqRSx@1kj|)oe_( ziy4v0B(fmPFzj)&*=2AfNEoSJuT`t$jPAIsnZq2XP)M6)SeAgpN~}DpkT41d;*M%8 z22DuQr1?-oD>MoXYto5iEb<3KL2VIO@x7X05Qr2IcD;cBG?uj4-^+buDhg<{rXo$y zPY#2V$3Z{oh06fF&F&B*i8RUq(zx1ABE5f zKA7uI!)bmOc8QkzOK^!l5hv=LVk{Obvz8^RfojwQSXBs%QMpoCu*jTppK$S82iyM`E)Jt6dHkC2{5IMkFeUNW@CW1T0gAB?!1E=+_V$ z`TKeaZG6HB5KjxF32IYnTLMFocBgA*WS+l!LuY!< zto2P>2A{61D7?R}YtyW(sNPo-?41?UYEmn5y4&!JHMg`EDE|C`RBP27;apY?em1e9 zV_9A0a9f`AM3hZ;?6jnbVm*$Ew#8vrL1v0JwpBHU`f+lRKShIAaNUH@Su`~9nJCEq z3Q3V2c~LRYz4zG?uIwbpUa+LBq%2jRcp~s~_leYUbvb5F$bODaaC)acTTkmlqB65* ztl)XqSf+&@Q$H^rvxrgX(pQ&+Ekq>Yt4qDyAKV86n`oNS%m7z}7Qcan&m6iq@O zBC7cRSR=)5uzH#g9B8h^=aTD2nx-#rNO4bJ(OAD?h8G{1ta;rHHFeADCuVWXY1lx0aRNdU(9o9dY98PmhE+Whj`3TFk*ugI^kv&AK~07=%O3@(F`WMm{c z!#Lbw4|7S*Br2)AJV)EoWEAdI*OnBsOwM$Jx;Y2=FNHwr;9rRF5+ND)dM_OH^$dWr77yfjll-UM7tMs_b_?ooj(hN)Y_s2}B`3}6-6$*D0 z=FcimzT9}nU}t*rjG1$b>Q{lG*|w^lU)tN09J}9MQq}0M7@pIS7JL6lW^IlwZ~kr& zX3)Es5T8cre8L&_UG^eN``KZZx>4a$l%Q?}di8?JCyG{3vT^+i8UeM&PE$U3jt*IQ zrAYO6>E#fVs=fpGJtVN^MC3*6yJ;?ZF#k zYxcy}K?~v8q1dBIeE%zL7<2p{RRIVLKh8>2323ljlvOQrT)MKO}# zif7l|c5I|5IDGuBRne8x#&wAmi)YMOQtfb5FPSl8aYZ8a!SUFCzdSVbGBzJSj?HI> z=ADiG_p^I0?yj%fb!qROi@WOTc3mW6{w(zI9Q2U`y1IBRR%4Y4Eqe)1VCpUm7C48U zn8%C=E7c-o261_duyHS$ST#YQtIMq+f~lg_*o%YIxhSS-tg+e>4Z9+E-5z?UZ_Yq> zlGbXrX>VTxt{-`41pJT7Fps%W3GZ}EhHW+v=fO$C*o8G3C&pNk#3@INVk&7R_$r}G zfzTzeiGWDLeE&IEM*d4c^)#FZN^?@ZioIp@bzKTZ(B-SkabNvyZ5c_S&bwd6!(OjGfGw^hq7$>^LEba*uQ&EOYDN+0Ro>+ zd`5o(Z7o8*yxf)T%GO$krQTt}XMC#O6h=r|>@3DjTC5d0N1k!v+g(`h!V;Iu;LjMz z6B|afDj4J-j572gPCC*RVDf<9M`jB$Z%is5ush=XnF0n041RpfeK>FG5ayAoj?!nd z+E&&cKUsdyFSjf`+cEQ3y|eF~nU*(aTldC|Eq8TfBv;HXT>Rs@*(trt*48Zf@v=fD zGJSPdkwRqr`Oe6}m3&g>;jBPv-IB_xfl%V!)ViV4+}5JR%KWvC{4{g^z(%lnO%vv{zBU@1JF68i={a-Lo9^t)iauovg^CP41=O?SpLv}N>GcIm4lcZ9 z?5;|gE>VBPlx$Xd8gFaazL%9qnIbCsWUN=DBK@Jz3eX!e;5i>ycm=#OXPF|YoGZts z;$cX}Ku%CT`M28b;*1fmg&PqQJ5I1j1T_+XrU$^Ef$5SV@?bJ#fj&_&;^1}p5Uh(E z6bhMAR~YhUKk)iST^5+p?k-=?=E2HzJ+06eHS`zv?_W|}w(`)>;IYv<{C>&Yu-8>F zx1w^m(dU`Ij9Rhq-IosCUQMxL_7R1`*SKWEuIA)WrnUH%pDem%Y+Y63!N12|NNZa+ zvu3z4-CrNcuH3k&QW!VLm|#ROZX)D6E&_?V%xj?gn3Zr6OtI8TI<9eqsSLygOf8~p z!Nq{N0b>gl99Pjt#xJnklRK}x4^&wMbVHzTy=WS$1N*Nn(H&T(mZgT5y~3Vnsh^#ifbjJ4>{1_AkuK8Eh18VoqNQIVD!aZTfx7G8-DZ+THTLT z7$=DY(}rlY6e_QM_lkZa;hA}rw?93!?3r6jGaD96%jpbxDsS0+&RMk}T(dZw z?43RoO1x_n8yBs0m(2`jcZ8DfV&BT>x~Hph$;|2mM??Q@(`WBqP?$gO!P)hzBXtRm z={-v;W^U-p`2NYf?vUGEKD#itJ8oYU!~oVmB!Y~u70kC?kvY@H$w;l!XYqs7fChH%`JN-F?SC+F9E z36Lhz^C=z2FjK6Ul|fi>)6pRxtJD`ZLcK4WB1$_zzs0+I}M&F0P2nn_ycoL&7{=#wT!TqiH(;gkch8 zd-VTmUhr~aU$`H!aB&+W1Qrlj8NrVUpmDRAL3G>Hv_v}nFJ{O8W`@u^y?HK`%9ZE! zL7h!+(mu(1%7G>Upg4u6?+lrH-t|y6y%Z6AkMS-QZXgv z;o{d3{sqEMBYZEyYY<+5a0S9e&;sUX4%W|7>%i<|IhGQ!Ec)4H43^R`v=zZC!4@JA z1L69~A50)`6Q6}BD%ghT1EeK%`|jPbp*;Y(-qd$i=sUOyEQ2wPhDGZ{R5tM(sQZ^zJRYJhjyuU~@pfE+mmG{ahGJdNchAJ1Xb;FU!4JxKS73i?s<#Gm_T)7Q zrT$W^mz&fGgU6EjNP&)PF)<+0LI1}DVi7Dbm={3}LlJ?@1Z{Ss1xD;u0mc)nXgmHF zezB;%6@lz3pCPfRqp)pHO{nGcKriSfTYhtXZbgdf7dNvIe#}!eyLm=>T4i-pUUpNF zBR6ShdT}tab!O$lo_2p`WvC)U8+-3&%bn=0r4x0c^)R>0L<`U`AL=qiybcpy=fx&( zO^w$?H|98D6c+J|a53MA8#5HMv|{aGf?Dg)zNCeTCjpDK3EBiczm4Xrrvof^Hgr~S z@%wuFdbzUzHJueqo3k+At~d++zaJnwsNl{Dwp?7}-K6PEv1wyFC>-35D|>=$!Y|9aR#QMiPq{ZJdP8 zt4dXuF1Ww(fe-dI4WEmB`NZD89BfsY9hz+^8AGpN%X6o3^%wWe`?uKNViz{9%4{2{ z9+xPm^+6hykio=!z@7%FgUm)gS;W>*xJHjDJw06l;0~66)32hz#u4LD@ec93Vp{Mx z%_3P?%!$QDwb5bp8@C%DH-2aoiD>|r!D3*jew9Z|r!Y8?BY{1D5!R!w)h>hGM*j(KNpn_sr1wLmIUWHznt9DH=?G`cRa zxVw1ug7LlMms7*@N(=icJ!HPbXf4$Z!d~)S1G~dEmu)aq$Xx2rmj;NAwFD3LVNKA9n5&Vo*gv0&J&5-{{O!^H*DCHhdFz``023>yPhW_A`inkx zZ1&G%UyVI@VN2!rn=whc2HF9y&@aOK<*0&B(MzyIf*CYlDU$WzL4~xxNrcs+VCulrM?|>Oqh;Z|TVA9aETrKy@x66;o8L*o zGfMoD5<8Vx!t}6%3c6oShFBsK(QI5Z1qHl#QmP4mfj9$(0>~Ue=rlp*!m070Q>Uo? zr>Mi@oq&<>A5lJ|{9ehlE3r>mtgKhk4ke}}a#;^c zy$SyL$%$`yPRT*E2FxWXBcf>;X~Wq7{39TaulH==Z)XGj#AaC`z$pb9Fw+cTjfol@ z|Ki9IN_*tUP#Uu@ZD=U%`vqx)mnOooHFyNtp+kN?;X?zC7?v9-zX7Xz6oB(8I0YqE zC}}Z_8^Gn{EhN+jFUZNJldhv0&{yz??7@bFq{d87eQC-siWfcQmK$~^K4Bv?6hIE z4NK(Y0xMLd$g!M~^hgJ-W{f$hHjGtrTB868jKPUQBCub;7l6no1j>Zo2YNwl$=m`M zlqTp4`hXxl;K$xx7j_#>07emz28ckoGdI5=zrYRXeXLp{0+;Xz*5d;r{211sVj!+6 ziIuacZhB~I(bYZd*!Nw`Q&;NfRk`<;)=vMPiuaRMK|f8Xg-=tZf}L*wd9g$-c)JB7 zP{EWJhLx7~$Og?uiW8Z`l$=(Q*2AGvVBA2!7lKw!HeF~qG+2&*?~V2T$!Y)z0= z{l|Dtyr~zcU&Gu^kjbOWsTmFB4-{PmT=)BihB{|uWto+B5#OKEs{8uq94r&0P@vY}LWznZc1vvGYCA6r7i_)PJ?qPOgdmV=)^^5ZWbZD@Gx z@{b?+>%o@q-^*S6lUr{2$>Km@(V<&zd2&fE^}*Azzr4N#<}cIX!`SfZ;>EAU{`$=3 z_aAO)dHDU!TmEZrOUvH>inp1_MiA(#0uHL-GYqp*Q6VA$+WEG3Y?v3AM5Gq?NCvIy zNVbRmX>nc~Atu;8wD_U$=^7v1~v zT_xj<>wCA($~tuPAS0Xg)cP6Y03sJHJs6wstX)YIO`~05; zHEG)ajm#VV`15;G`nH!mF#Yv)6!m{g?}I>ZHLMP}o9~pWEo$mJfEOilby%&CDzI3A zjk6?TvzUS`1Qq^N^__}Rky@3KQznKIwg zhM7vxQe@D?@92NfINyl?c?ja9$+*|F}?)>O#FyxMTft2LjU2%Y=!jVSKD5N9-Ql<&R{xUCvDhP#X5r7qBLJj&rGZSyiCrqb6l{hE?qaOsW3}TSq zGF(8v_Ik|pi`!djcu;!%>1q4>1IBmG}gBj*Lg|N%mBE+C8k;=P|l3(3`(7WC5}YWM_r=P3H>#4&{v}pK_-aDGf4y3 z!?Yv~dpJ80Rp`Bj5CQgak27vm5T6s01xg7p0M@ZE!CwDENTW-nAwQr%2Q;D~+a$#+ z605M7c%+jxblPhltL+w@h*5Al`5WhAJ5R?{R=Gkhm&+`wzn_lX_1cFDy+#GFw%(+K z47{fbmoMx~N$Ht8KZm{rCg8)tCH{ikV1a*m{#Eeuu5QYjJ7-pkXU>x0oJpRD0IlU{ zJ#UxFIGGF;fE6Jr1fZM(Xba)xXcY1dX(8IBC$J}2T1vH&V2bOM3@oq#N<0T^83k9I zV^S&X1?V0!prB~d-W8l}pi6*+O0Rq41hfLH3;4wh<;3WMAgYx3;$U+{&c_~uzJkx) z^Ez(8jW5P#QESFGQdg-{t z40^-(H0u4G%(^Fce!o8co>7a^Yi}CIcKa8CgUDHpvDae3a;RXAL2c+MMv3pc7F#5Bt~hJhq16{0Uy?m(KMMKMTo?oVI0Vd zL2RTr4gYEgzx1QnvDl9(55YUB564~Lr(BJlrW+@SA*3CH+$jvHq(X9ma4(4<(T!J+ z(vW!~BfD{>(vGV(Gcl8mZRKbSB8?^=J2{ci!iAm_xJ2YDeTTD#iaIwQor z&-t>l4b1Nn+PYe7hNPC31~PrZO?@zb9$@+a9|@p#Uc=$ET6agTI(Imi5@m-K){_(O z@`*}K*vbLFTCIxCpvBm1PjBToJD1!{iH*oW;-{AY#)7a?Kwt--kGljM0X_>cc)iz< z#rzP!utI_n1cu}ItHuMpS8>|Hny5_@!-H<{(*0+CYNy*aveZ`R(#U_Pk z;}``$iD}x5h^2XPxy@F-q-E2(bxdD)`)}^wc45bKt8bcfE2Prg=Wa?$O>viGSoQ`N z99TH-(ZvP-_3L-vhE8A-Yo&)_tQ?TTWVS0^{jPN`igRIOnC*1xT4bE11sNy#m3VOi zuFqZzUrk~SV8XzpOkgWawa$y)UDvSj*`dbWfqYY8$u#SuJ9h4B*^r;VMjzUIVb7!Q zZ!Sx+?3d}((l>u|{uPhq343Cko+R!|3G~cHxx76E*=iFz0$c!Rh2@<&4nqR+H5)n3 z*^EWdB*ET_({hS0JlEJF9(6JiUkHOQq;V6TD466F!WQikWAThgN$>t;B_+%D_X0^v zjNrjj%-BP**Bcg=JE%!=K9p3NWxYnxjA_m!hqZviC%*e^Lss9mzO*?K!)Z841N2PQG~1GVNt8MXi;|M`j%FFBpQ5gSZ%w))#C9Yx z?CWGsr0m!g&xjzWr3|ky|#( z@n^Q8E`8kt|Gw$I-|lX#UH|iCE6$F|baw3%x&*C+e*eJksuj%{0v~|rQkO*z$nRaw zH@;*4&`w3{qxK#4gLcMY580dSw9U4Tdx@hs&Pvq+RIFx6ROlGXKsX4pi=7ak+Cd+r zVKT&QlNedC*s9h;6pkXYd?^GF1Bqi3JOt)EkZQ0P37$(VWReTv&V$h*qc&+213CgT z%hs=-fBEIijyoHR=X(8)>8YvHQgmO_XRn6nv-MSx#oOB5Ce=2%Mwi`I4k!^!HOLdw z(^p{(LVy_cp`Y>=Wq@s~EztTS1>Je+wBoY1iuvdFhU)SVBX6E#NegafRZWcY?aB9W;c~&G^$NlY%-N_)lEq@ z3@%aVEcBGPEoX%gxc?H^KVT%E1;ZHhu3#Vo{smbtXN9a65-uSg1CYP~F5Xn?OFT!i z_{QW5A<_h#3?RgH=Yix`PP!C6f*lL#szg(OOF>_KEg{9la0)QZfPDhMKvS@Xpfe$5Mo2;-_)Jg}Pwg-oH1zC+%UhOJ+Q-HuGD~&q z?Cj@XpkBHA?%bhWk@0h&2Ln5Np>+LA|2`g!>zjk10B?nF3DA%+>*4jB&Z(mmsFuO) zT5+2i79z#xA^*pMOGm=n;M_pEetta6Cjz$)4~~t!TAFF}+BKn!%u=Qfr64bQ{JxwdxlT2+6hf*zW2C)Oqfk0#2^a1gJm+Afm zFx1`n>Wb`;$(rxBWw~`@N#Uis>#d0CRq|ajx!PMEWWM^|JY&sFzqtR#X2t1GUlwvU z`yimtKs=ZhRe{}0q{2j`f@4`u&G|V>td!Qu+SPIdRxkjnAO~UriWAc!nSlnT7ZUct z0}^JnDGQfm5do+MtPLn4$q$S}iZt%rggxhD!}!R1vFOqhCpfC$FkTq*jPJzXw#Iry z`tkhO=kfO8L1-ThIk75^bwW~YEpBJPA|d)j@D1a`K}GlxP#keg>MyhupH- z7vy-4{7E^rS&rw+SIH^4+=yy3I1 zGa+abvkpvb=(Atn_hyQu*)i#UL})O+4>ue20byo1VbU_6Xox6muA|gObGh@ ztiJpEC(Q<8gaKWl4;1u)i}%6jWIeUXg5jeI8#{B7ZAogUyxGQOAm|M!3KBlN(eMF_ z_$Kqlbj?7647gwc*guo_wThfZI; zFYyK4G@CPt7)MjG2VeB*0~(j}@@MInX^L0_@inP7u^ggn=4^AbdDKj6l(njMlUl7b zXi4NEbat{Y0fL=C;0#p8bt6E~@Pt>X&GxX>oKS2HEvQc$+hvqkifX%c%f-a_eYicY70+@OuzM{=ccT1J2*}0aoMKdxUd8Bb6*2g{zt!G3MdW%RQWu1*1=TU208vlHC z^Z15=IRalC0-Ig}t5&Tc5BWlA`m8zo7E*7Gm%@}kZ&!qx_C0vMgkJEYFF+eKXz2^E zMDtr-4fzrpB!Rz3D#dCJCcWphhA`Rl3BasCH%|AG?j7BiI=Weh)jGefNk@w*0N?=p z!?jW@1;{&Y9T1eH@GO}ffPD*nzOw@K2f-vzxN#s0xR+pDcvWok>2vbLL<=Kk&54Qf zbEjjQnY!^uT?>{(ESAWU1ukkXG+DrE**`&h{pgh!kRRHsfR_4^L<;ToLUI9sfNa&}Ig5Ez`n$pJlhs9O!pZi^q2-&F=4l zvjt22R9IjJ444F>-v`>t(Z~FcHcRon5FBRkKNTDpIQcW3Zz=p2 z3Ks!nh8MGISZXGVr?GV`HHcSYstZG=Sv6$pVjvYu%S96WPYM25g7YEfE#{4uu$Zjl zTP$89re=!qG+3t##uTT_R#H2ZQ6;5@)hoY~;WuRXlnhG&zAKj3%c)d3X5|JjR>Tlg zCZ-NCH^77F1rW7&1+3M96h-1uK!O1QSIs2tiu^dC3{tmYjN->R*{HV{P&%7nfDs#P zU+nRBu3UL1_9(vfo!D2gzrRBTDN}3+?;rnk{4IPUHi;|Bz=!$}Xq1Eo$C5aS1gS{& zIFS$`i`))eqvq7=4)N&YgKZcfJPWPfr~GA%Y^FcKl;jNmqRLbJi9B3==I`LH07 zu*_LNKz}GGpmTHr+&jq!B$eS>oIHeO|Mnj$y9Gv_HQMY%Vj2_5J6AU6HrNcjJG&;= zqb`DBe&VxQl0sogv_d2OWPNIvxTR5Rg=@SP>R8O{|*Y;E0kmVGxT; z5SfJyh6>hX!W2d(GT1}k$Qq4F>@siMPMKp;DmwlZmAIC!+Wg?v_u_3M>$6CF--~$O zV`bTYI=z2$>(t+H5D|8(zy2KuDypA&-f7maE#I=EhXxjBH9Qv0CqX{7JU zU#sHasbGZzQcRY#{&}+R;2jm@ z5x9rM*kC~`bQv6E1H{)z^hlfsnVOeKKd1WdDvy+1rvNTqbO-cq%|hHD&|$YghuCwu z;Y>YHBKE96i9G@(fS-n_I2 zKtZM7Q{Yb(3e0nNlLBfhXH>E}SBB+@C9Kk-|G^m$9@eSHwnDCSANWxwRQ>{dG9tcC zJsZ}jM=fV8V0Z2ZJV^)#sX+`>2-c}15+D!*UfkDv({gnXRkv;`6gO$eUx3x>U+Ubj zT0P6H*SoV|wYpnJ9s2$gHhe8Hbux7u=yn=xvr`aT^`IW!qor%q3?uUxyu24DhLJ2= z#>?K7F(R35M6Ff3Mp%j!RE|Qe4Xar-OLJnFi9*Cg^T*da6D%ptT-@s?s85GMkn3BG2S;OX;Tju2E4Q%b)9KJ6r4}i*I%Op_wn?&l3x0Ur9&u!lJ ztNZGeM-I_0lYm$L@;CqfipTsTqED&-zi_i}qEvJ%uTg4--DIyN$ZlfCmlgaqXAEkES(NC4z{GM`{ROK&iZJ6$K0FH4Au^By0ab(w zO`{I%P>9TlY7rw%JBn=BreuRh-;sVPrFOvQDxy-_Aq~NY3TQ}wfXU&~>q3a1Ebo84 zH{O3zMo7>LGv43M2(n|d*BY=8dlq;Ci~*nzK~)84mB<4GU&%`UKv6FV%?C+>6DS|J8vH8~xf9HK zFzkhBeV!{1N~j?2c`3H;%h-9G89V=MeD{~w#xo?U2M+mTn`2k72zHR7Omxc)bAT8X z@g5|_*|3sexpY(tF#cg!UBHQX@u>KWm=%jjj+7`q7Z5HMkYI2-ND2q>PA6vtGA~^H zDrUL*52CwnpZJFE15COazAbw@U(a?*T54P=4K*b-X=&Vq3mV0cjZqdfXBh}6P5d7M&cb`a<9Hpy(||{lB}@?C zfaMf$43rYqCW3hak_6oJ19W;SWkZm<>&PwniUR2G$s`ZLe~!r&nvh++*_t`cQQsjr zfscj@%kQt9J7g~E2Pd#G-JF)2P~A|xAuD1P z_Z|cOJR`c7WE%3Q85XP|HNDgHILRFWMiOKemi`DT*!p`ReTsmTkdZ^+QO}KlB`gp4AwU8aj&(6uq3k34=vlW&U8ypcFe-OU)P$kS0<){PJDO9qr zS=H(!EBu$z@CwSsXL51w%!*f1WN#YKn+~+%f84q1=&K z`$log8<}J+had1eU_Y{k0frmHnEwH?iiI)|5Dw6w>si=jA{H`hCzomokqI1MSIEG~ zlQj;^%}Rz|Q`*P7?4|vcru?Epi#aE+#67fcUNC>*!-JuFipz2buD+N*u;r&`7A!dP z(=7w}Hy$sYckC}4H~!_=ys157&uCj+-?+NfCst^r8{}G*xZ;k(^XL6^b*0O`&YBQ= z@ur7to|Bh1XEQwf#;3s3gt3Kh@N!fIdk*4LnXux>pNZ8Mk(~n+#IN={{7wFK{$qYN z`J&upia;7fR^~@)wH13mLZUOekF0+H>REsP>ZKx>WC1?|-Aoc&If!ACh%5#M7xHs* zg@7!e^JJke(ar$N3xQZ77^N70lA!ha3*EkOu6^6~xuu2KJ?YuOTT9lidNWv+rVXSg zP4ii3d#llHQCfpDfyGF*yL~=;iIm5dk%q&%_)sL%>scF$)9|z-KglMH$CSxHbQo+Ky z3;3{%kh3%S=@elp74+_PAJ`OxUqBZSPX(K3ofv!KyH=cc>la_#8v7OAi}P20{`tz- zFR3*ASYzx^>`)_q#CH707jKb7&O?D(O z($i2QdYNB)$auo|s*yfndeuakjJVaHGO3KO8B}_ML8X!+%WGEYYm9+`upP3VvA%1i z#oHNdWvq;&`W2Lk&tw8jRs4!WWquPOqs?frO5U`=#cHd=>bI`5Znr*e1+f!iILjf5 z!&+@tTMGY1uCDHl6e4#d(=sl1D+npcViXeDzft~#Bq1mzvslq4&c~s%n^+(BDux-W z7dVLkus%$_#3F{=T+pm;ngkAk#r`*$q&^AHYHI7Q!4KLpiyW1CrgWD~_T1b3kAC{p zW8eSvMhU#}_+O-vM&atZ;`Q0}MXAbVGd;D18V!!b4$^Dyj=l2#K@Rc66_K71i4KC6 z`#RUQ;ayo7)_g3d7CgxUqQ)}}aj=WmnLkiY6B9KG!tqwJs z#=AK9@Sj8iAM8+IeB(Dels{A4@YxPfF2rDgiCKuf5I7hdXqc$MxCPe{QVVbVghy;G zec<|MJYrX1aUq6piPup}!8T6>pVAG-Sf6@^pP75Ty5%*OnUttA6h z9(#UMa2LLxs$2e1Sx04YQaK+;>B}y6g=Q56Iy+_+JPPe|P({=NXkRw0UM-;!__m_N zOAy$)BntEgwg;#HX{gt$;w{dwine?dm$H8AhgMc%wQ5t`A7}hQ`>|U7p^yY|2^1Ic zuH#K74JXSJLBL?K7Z4BJ{u>RHYk~ydQ~-&Z%A66t9YHm=RCjfyw%yfPv!*C?Pu`ra z#gRF4X1D9zep~TCu-aZ))sRuWu*S`N(zwWMTGUuFSet5bY)ndNn_gGBqKS9<6IE%R zh{`bdbEJy*x{=HNhB)S0rR|bYNprQYZKZNtu`8hByvN76o4m) zEW}qI2$3E#O~rFZg^Uo$ArgFrsYL%E9$Ylsx~wu`>>-;hd&m6nBKW8Yg~!J5rt5(6 zLv8I@=_#r1j`Y|W5y_WZ5xdF^0S=;rHo2IG5leuOW)=V|R*4@*2F`#HV1ASmvPD@) zr-H>Ngug)!++c2#uycbn*-Hh9~a z`yYC3HCRZ59uHAryptyJxFB!k4DqkRF#qqLg!x!lto=EN)y-PqUzTQ5=l=))-3{^V zeeiY*%wrC{PG?xB-43A!tw?zfvWcwP`{8pos<6SJlWl_~%9s2k-2tox=r4h6h*%3e zc@5+fc+guAgpUN^ecSdJ|DWo<1+J>=%6so~?&ZP-?nB-naCpDuUf_zLfcL5hh(r*@ zw*}-)co;yeNv%_jF^@@1rkRW%wY8HN6HPRBLe!WhYKduHZIWrHOun>Lr%8YFwY16f z>+qYI>b>({`g-KNPme%{% zt^3+0n{CtA*6rT2XZM$}RVd1{9=6X@n(ec}W!DTG!>@Ic5g$1?$i&FlA?F+y0^MNn z!0a*N<7@MfgD!Q*n4hKa@f%_q1zk1tuNW$3gkduyJ@#tCMSjZtE*Uy}k-O9V9vMHp zP%^pO*6?k7+Zy+dxanK6OPp{#gwM4lop!>sWU!Bh=+|)FUTEDeV0&R9a{>q_yp{CdR&oAD#fj&@IV3xPGt(6E=%hHpnX#h)m!R#xz*+`U^a$J`smnwPugd1K9k!^_NNh+L|G zlj8huQ^N!-U!nGpe{NnBNc4BC&X*g`5@>WPS(PAzza1~>!%7)$iU?-`As4S(TOd9Jbm4SziF^MnPn;?J2% z-_4ScKFSp;O9}dPc>YFYsc%pPAU@M|&}r`kus0L;vV4~!OP|N`Yq7j8mb+rP63eko z5NzdGSz?J=Aqyehn#d3?_z7YA-T;Im`-Mx<2Zc2T$c>iJMq{m!n~g6Sr9cZD+Tn(7!rnyWrGLZj zBnuo<9b{q)3UsHvcTqYl zzk^8I$XmaX%Kos6f4xUUhif6X{4EL1i0HEy{WapGL7#LX6Zi6)_#yZlugy-4R)jE! zbco@S-w?8ssmacH!CR=QbeL-28=Z%_F(29SPe06@DsOo-UZ@Vi2~pnEv*I7~{EILC zTcaTA)Eg+bil1abEl;=SUsYLv6p--n5JgSzBMVEx#8y!UXej8T74BDj^LXCB4iwM& zuuuA7&zF7b(0yAStVn;-C;gbmtfeO+Nxn4@b#@{BZUfapEl;;6bVePRe;uH&>}X>Y z8*V}Ww%xTPHr8a_8rYGfB=P9^TTB)UH?=Bpmd0r8kOAWg+cCeyt}zcyu~A?&GMwLJ znithX+uVu)pPizjVaAhF8_gC7D-6mEwg=34iYAZHLd#RqV2L8;jwH>YF#8cTrd$g! zKcWj1!R5TpeO3gR%W2XR6kC2)#F4foaIgUm=MRext3%lW+&+4GPd%VV3W?O^N+fW+iGnuNX$ye*5xKQBJwO) z7Ze+*%WVt^(!%&KGfZ2W3NJ&bX#@zX4`9a`B1vee-=#$cu~&(<2!XLhl(tWa-h$;U zjI@?Y`tWUAzeEAAuOD3V(3a+{6!ZF}zg=E;^SmujT9G$UN#U+?_oiEK*aucp2(13h zU$?k_eqO}CR_gP`kV($ZWt_5~>A(r0QN46#Hv| z`)sKzDGKqm@yFu1C7xS@DdKm&wJ9L3DL4QhgBI{BmP@GnQ#}BQx0-b>B7PkaG%q4J zCuWX|cD(Ls{gES_gn2=pqvsle~T~&q(8>T|cF^MsDc+j{) z!>Sr>{ct*kezh|>Fvf=C`C{Z{sg>4^cUkUI?z()J?5bS0z9!XBC`T^A4#LYK66<0k z;jTqdBf^^;<)t!1LJ?Poi5-mhQ5!M9z??J||FP~Z#v0^A;kz1vp`}h8@0%p@s?+9x z{d>{77N!vZ|W2;-1j7knGS&yHM zE_Q?@PxBtK;-7vPb`)8UPP}l?v3NT5ENRF7Nli=09VI@Py=nEom@3EB*VVKoNSjq! zeLG(L$5Uy$f6i2`TWW>HXm?bqsZ|O0;tn`8mHtg{`eI6-SEiLjYY{TlF@VMo#n`I3 zj(x=yYY$(YP^DYGoYhpN$8W5!t#7P9RxdBEVq*Q?hL9?3Ub z=GBR-CBy2~)}+!p`+|j$*iE1=3WtP2sA!5!{Eto<>&lqQ->wE*(agTOzX+00fCAQA z{Q|8b#p0`9UIkWCml)3TW< zWb;*62YT}i+4N68T(8Q|LcB1XX`4<>WuTZLAKYV*36f(%F6a4R_NEo`rk11oe{1rV zPx8YuOI6HXdGi1j?-01ZC+fGt-GKT9VoJRq|oU^%B`!!UGE6guX_5Y>HT&Vsow0JFYT*z4nN=3K9Uod_~k7gR{e2igS}$e zy(Pb>9$V30yWqRY6@9Dk>a9phs_d@*(O&+UM^2Q6&-ClwLxx|rA)aPvxCB6F%!;yOqX#QrUOJIKAs1iW?>W$ z)D(6$>~h$LVFm*>?mEqBRgQK%fXvv%k_z@?!JHW;XJ|r|)+YRxR=nM;+9%s2?1Xsh z(!9j1=%{RE-aI8cDmp81p8t0&XguZqZHhf1G&I4Ul4MUbnG)^NCw>pm)KIfQC> zdjhs^Dpqy3xk@q;GhzFtRYgTdMi>Hd3S=nTXm{B^v|qQ&W;+jvs|wv<%S^~f)a4}C z8H~}GLWrDa$*BvZn2on?IN$OyeyKh9*uKK9P-Vnm|29uep1Iu{aOp5Y!ytfD&+<5AdKeV|GW^N63{v+8TB zK6+sN0f%(RI`4yzjq;`49O0U6I$&Xqe*cgFD05}9t%{{5^|Q}gV~!_$fR11Zi!@4;;E#}E_nVh8fRB=d-WOK5x%ve z?At`yhfOMeJMed;WU=Xzk{A((wT^;#78kdmF2Wp{ zREM28g^@TNU0k3=w_tt6cdgGS(8X#<8_=SK8H-q#bAde3H*7>c=Nr=E z6YPRBqZd7C^^0&Jo{4%3TB-H!{*LIoBu>hN2d5ONHPu!plWm(^_2>Dc8!o#`)_Ij}Jhhiqfm8T&rgoMYdo%@=4L zA_ZC;J5Hp)X|6~_wvX&_^ekM|?bs7rzM=$i6D2EF#^^pyZZ0ZnPL31nQOP3AUBY?0 zAItdxhs0Wd%at2`fM!H$5i^f9^aFY13i_Ai5$H76nj6srdCZ0YbNpYL^^I_8L`iP^ z7)k^K;Tu2p?l`1+PpAvC2C?3###GDsDP`;P3+hW0rKG+fZ~fAgUCw;$@K~Jh)c>7h zZE<{jajnBqi)&Hs!ot$hLV!k#kMzI5$f($rVve$7*`Hyn7s(J5sXuIT!9UgHf*-fZ z6m}RZWf--?t&Y}3au8_=1@}I!yJBgW{5Wu&0Z9-|IOBj0$(>nSQ=#PMnL71Jh1Is~ zwKXf_b8Y4>`lkCNB?r_j-LWz)B|Bx|($eOY>0k};!$(0rBhh&W@vmaK^Rg>A0PfSE z1x`J99a>fFYJivtQlj;}YwlsERz7w3l;Cdc#6jda=+izfl4-j$cK#1i)i~}JaGSPt$`g4&*d-mR2TzdcggxL4& ziNaTz3G@j!Mpt=J?-QuGIDq0jwjadF6F9Vta-lPTw%-8Vrgka5k|ooWQWaM-_)4fv6&s%S+ZI?+riUOW<1#>pVPq{QXLxe)qHZZiR4-kMN7 z0*L;Po35L_!08gGj^tC35BN1608WSvVvUyQDz!ck3Q-?bEND4T)QGk?^bwKiI?dR@ zdS;z`x38XYdI`t5b)QMS^6#MgDqN}dh{lM1c;0;w@p*(N!hrSeMq|J67?vQe89z4$ z7(aw?(>hlOyvtc4!lo>UGKRLfinys9{7)tGUy6Pz)w!V{e}gM6&9x!FV1qMNny74b z&Y$mWt*mHuCL}mpRh_~H`AxC@S^6Cjso_e5rPc^vR_}5KbJi+f*i2YBhSc7M`0pZW4$da$9Ccc zdESb3RDKhyr@#4)-|8vl<^DFtNS$b((33OHT)`R+gca-8zDKTf-u#De$~ZYl9JwN~ z5cs_u)_<275t&xu$_|ol1mmo?sK%(n(EhYC9&tm@b)N;9gA=jQsT>#_ESWzu{8WPP zi`ZCH+oRz|4(&)wlLOR6!jV2nJ*R?pAAlrs>G0me?uYoENB6paFUv6gqJzF68!un( zmsZ^R!B}=nesEfLruhq02Y(5?4+5b6Eo9x=Jx3W|(e5R9ypxd7A5O#JI_+M^j66@f zN9-=|((VJ`XZ)mgZ(wUA^mgLiKo%}}aT-~NJfb}hX7hF4G$G8UJFh(tWj1}ec5h*(j`DA5_kk=^dPKW7vL8zCYWKmc7@_WJ8A8}L-Dd4R6!*W>?oDjHeo(ug$HMi$ z$IMw5>i`S^?qzK_5l8_v<9jpiTCiZVlkH&xB2_1zD(obn0Dee$@a$iJ`%0wg2aX=R ztzaFbAE|eW{|QSM?)sRGvGT5tuA#1b+gg>@=AmY#rGMw1fv%3uA?2h}ke64qK&kBS z@91e$R`d_->>p?z>gw;Kw}7l4NT^urP^3NvFNX4g{;pPKU2`Aq>yc{**5Z5c;{d+4 zb?oYC#?3M$Y{74Rc(o0`C>ZG|v!h!!*wWV5+BTr%D!!QiXx1A9;z6y7WN_OASroPd z1?obPsMPuRI2hZ|HZX`PDfza%JY~nOuAWvUKOfJhbD3E^wRY3LDnK|0bi|b*)Tde0 zt5?+eZanM9$km@0L@p`h%`3`A1{{~-xB4M_(rVILG z5X9dlw8&6ro3do2e&{alop&fF%5-2o!^%qaLEp46~aP_irGqP-6P z=Ry^WLijR6WNzyp=&<*wMH{r&tXi>h&AOGjq5!^HWv15Alq%*>#h<4gl0MttkMNKq zm5iaQ9)9!&>?at6{y7+9C+rvrj}!~DVlzY7rm!m_F_#t%@4r}#Ea$@$GXZN^3ih^1 zMs!#zqWaP?Q=5rs&TP!MEkKoQsAeA2W&srELhQ(}2t7?P=5m+7C#n=@>MX^u*#&Mb z2O-KqgbMUQRUk_>R?uqLT_8;@);`vvZ&(L^w+8TSBiqC_BO+)k+s3wIkEce~1Wv!m zo?-X1gY0#j^8C;20rnVsgnbkJ+i@1ufPJ0)j{RTuD9*2bkd3jQvwvaVVyD=@ zvfr~w_B1=q-hto88R*p(oIKsi-h&jq&E91nu=m*y*bmwN0rh?aJLMxdJ#-+h=n3`{ z_G6q*-N}BhXY6?T;!VsEfZI6YctKs(RNTUH*_ zKaB1Njk7JJy?@uh;I5reAN}YhVK{<+66RWD!BPD8efQaG^uv`A^iKGDJF0e4SUH$< z0vG9z_NHd+@A1D*d?Q(4;C=$Q$9tNG`XCMT3(eusFZ}Md0eYsUqqih{!-k}cTYoE3 zwu3T1;Sci1_@{thNp(`UG>RCIPWgoVsjgagT=z@3$W~xS#1X@jfsX}Qcpaa~;LPBq{K4R+U^hNZAy0;8OWmPwo92bS9r`wKi;ro& zX~6r@Rb%8NK4zQ1Mmf;uF=M9X%i3qZ<#F%F_?YE{_Bm_KM%h2LR#~e+g;dWO{GSE6 zt%uy!Lvq_8yIGLlddP1UtMH7mNnvz9GfHX&qyn#+-OuGFk^dioWfb%1F z;QSeIe(cZW{0KNdGACEYftk2Ma`nf!GCnI;Ea0~ToN$O%P4x51RT(hO-9qnyG^w&T zm&E*6$~L>iP}`b7zo$prHv&jzEP!dbIe1%}UW7M_ARFaqcNKt2Koy`G@719Vtp(KM z`#N0Lm|IsojWo{yjsu7O;6=b`z{|*g6xUY(=K$vc7XTLlui>}v0$vBa0l0*GuK?b{{r6F? zcR-u>1&z$$nH4~7ckcE%4jaRlrqlEsyG?hLBcGZ2d<=9P2OU+tz7AK??G3nY0Bi#6 z$M*w(`vC_54*(7U9zAtNx&(<3xF2^rvWb`uTflI0h|Mz2V4ML1iXgdu%`rS zK7pD~pyut64jMmu`w0L3p#rHY0aXB;Zi|{t+>uYujMggw?&H>H? z;8BMXQ3=$(rF;&lBi%Vu^HM7=hh$d(DgjjhwFQrX2V*GZ2zWqN#RzyX1|FP&G6pla&M<9hGkirp2;fU69=k5ugMw({;#{tg*P5_<*JP$YtI0bkC@FL(e z;AP}Bit8(YbAa;zxRRjeBjCjtcrgZEjDZ)hNKm#bf+A{*#jGDnOrs37XY}@HK~qw? z8M;ihm%?Gsgu|Ypeoy77eu|^j;;Bky!Z{{zsuqEl`jVgyNomLw_Huk9*?t=E4B$B6 zS-=Uva{%9*R2{rgid(@_9qsos(i9<}}|9<^5w6tYONHkVvw zOj%u_&@5(*mJ$HTsJ*v6=VCN;CrhjhcIztSuo18sCEbGSHe9J4-^q6P2GaRkX_xTM z6@b@TOZ%gx`*TY6KUu1MJ~SKuFVSqH=QGgjA3(3qK(9~!3|f5xT75D_E8--yG9c9R z|Grdjqa4J=_i!bWT>>{*`#rWOdW_00M6W~r3!)z9P7;>7nH}X(=8W)gGxf7$MiGFbs{o*A0#Yyywljs*Gp|vN`Cr+YIoJ5~E zi9T@>ec~kglrr|N=TR|o`vI;Wg4c%Ia`x>BXoUFRpK+LbEb~7z+kkxsh{Bi$qM1St z-D<_WQz~Zv0w9mnBQC%vSj_*0VD_&NGl@m8#OI;Us=(}F73TNiF}t@0bBA?k0m+!# z+lcwY&FI52*?!D>*)Xg2SC}(=k{!W&BNzj(5c71aFhh0$sV~Ap*a{2b3TFS_!d%@B V%-PYbojQLtAN=*7zd~Ud`%m*7fg1n- literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/images/collapse.gif b/renren-fast/src/main/resources/static/swagger/images/collapse.gif new file mode 100644 index 0000000000000000000000000000000000000000..8843e8ce5a46781defd33d5304a0cb4191e72546 GIT binary patch literal 69 zcmZ?wbhEHbwd`J-OQ1PRqNMh0sDWgikt literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/images/expand.gif b/renren-fast/src/main/resources/static/swagger/images/expand.gif new file mode 100644 index 0000000000000000000000000000000000000000..477bf13718dc56928f313ef6eeb1c2b1a47db69a GIT binary patch literal 73 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 I!JdTtAI=+^)&Kwi literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/images/favicon-16x16.png b/renren-fast/src/main/resources/static/swagger/images/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..0f7e13b0d9903d27a9129950b1dad362361504e4 GIT binary patch literal 445 zcmV;u0Yd(XP)rNm2=6wQ7&2F}_`h_PI>(9Fx!5<0%l6W{u0OQ#*rglqx3__&vD?|#%fhn*Mn&YY1i+JQHqPvZ34FR@_E%P@x zzTL;Bw#nJXWY}D7^bC>-bx{t|^|R6Oci&MKvov8Op~S=}R=h^p-=vZ0uqG@LE6tP7 n92{cY$^db6>&z__iT?Z#Z8BG|DVcT0DjiaEd>Z!7_`J}8! zKk_$1lGm$vJOY&DjT-(&VGn0;R`iN9=1aOuG`H}BlY>&R3KbGER zB2$7euhH;y1C_LTQex%L6khZpkjFn!ajOUK)f3JLz+I;CE@(N)T)CM4AWjfl-(04= zrsMQ)#NG6nr^Y7!6LA;iHXh?UOFE%hhy>7dl=;I$J>g0BH_r|_4ctEsXx z2sDIQnwa*rcK=*3XUC$D{I@}DTNs@GCb7dB2%%nV%jR){xktt;Ah09op7x@l5D6B2 z0uBdt0YmcN!o?lMpu9Io(1&B1s{TUu*a>2&>Iycx__fbDRM8PYtLt+#G*xSt(cn}K zt!~W2{`9r)xkh^xodLS&FbYw`x$t&Vhl?)#f&k-lZIs<`$gTj{^#^HewuJz(WnUZZ z{Ty_aE;^93bhc-^^k6ZM!^e~$q5!Zz`XPta{a@651gPzaFx$&%IHL6hx$mSeAa#n6 zLkyc-M zs$qhBZhCNE^aIEV)H_~^IeqSRnvo!21Qc`Z;S9!IqXl4K(RUImejotzuG65LVuGS# zcqp@OA8~ln^4c^VihUew)IOX^E9KMtvSvnZ| zC@rl{f(B*PA26aFR`|X!!I(7x_|kq{rlqwhCia+CfNbOg_yYt0bDCc4g#h#`3jpCd zNAhr%4#Ye{i>ni$fzY%r0IS%l3HHZ4tTjOi=JW-t_iG~)oC!2C!52Cc|TAPaH zJ}l%m9yPmA-4#lJea@uf$a`(1;={rL2f*8;7%icbF}e^_`X#ndU=SI0nIn8hXPXHS zSN4rbF}jl0HWx(_`q`-SRa9jP8Ab!}sThNkQ634k=qXBVM4`o{M>qrLJD ze*%D)S;wpxG$d%FcDf-6%zMqWA+gw!C1~T5+|ys$G3Ksm&x59Lyd?0l+LWSk6hc4~ z+yC>|4f;X3#cq3!)>#Mvb-^co7LMrzqWeKB$21I>tJgaGFwu6eB%&j?@d*8GAx~In zI1p-lXVKtcvY7;$TX~wjYw|QhB%q!npQES%F~%Aqz~pJB%rNu!xAj;>xZt75!VHju zfFy%B-`3;Qf<{h94~I62zcHv}D5pS-QCN`M8K1>jN9mpbrFk=5no8j!00000NkvXX Hu0mjfOavUK literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/images/favicon.ico b/renren-fast/src/main/resources/static/swagger/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8b60bcf06a7685b9ea53983c125e7058906fbcbd GIT binary patch literal 5430 zcmcgwYiv|S6douFYJ&9 zoHH|LSE(UtsLIS#7_-&1VM>ivN@Zu;-zA{00&N^|8r`@w~u}3a1X>=27;pf_a{DPJMTR$JSvjrVZRL?J~Ga>i0GO0Y%B;(7M$}2m+kcrz@>Hae2Pk^@b^f8%H zL>`N;qJuC@Oe+t~7I z<(F|AfU$#EfN{kFKA+53u@A<+4YnEIf**{2=CuCE#{h4Wo9v-X#BN#D=ro%g~u zG`=OQBiQEDZgc6n2RYf*+oRWbKVZW9eJJuGNa8A-F{8(f+y@)q2tylad}QmVTBh{m zkpvl@O*Y<9#KzvA;3if`|g4qjlr75YyFqbGlV2Q--{B?*ERj@$;+A#v6A5% zKJZ-k(ti_bGM?eOj#f{ZHOKc6lK8&sk-j?4Kdjr4z{}bU>r#UnlQAQ!`bOZB;Ct>?+|WpbgrOY2zPu-B!V?-m447=gVK(*?-RQObKSO{281uhZ-RJZ_ax0d9HE}&gAII8uJO7-x&ULT3$-hG# zr#*GDR$v46R``GL&)??M=Z|+Z8{*GeE`I+!{6E}3tWV7S1MCU*9ccYQdsa7AC-|$l z32U8*#-^_c?O%nK{oI ze@n2sr7p*=%uQX9Dk-qo-r2V)7}P0ZWaab6B%)NcuSZfL*ZERjG4kd;J~ udLgV-)@7w`Z&hkIdqAlS_J#Nx!E}|RnRSkVm|Sa24|P&EF^Huxf&C8$As%)B literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/images/logo_small.png b/renren-fast/src/main/resources/static/swagger/images/logo_small.png new file mode 100644 index 0000000000000000000000000000000000000000..ce3908e3f275ee790b38b28bdd03084cdf46bfe8 GIT binary patch literal 455 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX3?zBp#Z3TG2?0JKu0T4Zo>){e-JpKHLwvhH zX1~Iguh_m+$ZAZ!g$?e*UTJ>#yA34>a)p^YgFX-=DHR;hT%5Ezl0x zk|4ie1_1|y`S<^yFHqRu|30Ass2u?UjxX+x1S
    Eakt!8mnNYh!~056i`)Z#nY* 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 z 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 Ef*R;Uh5!Hn literal 0 HcmV?d00001 diff --git a/renren-fast/src/main/resources/static/swagger/index.html b/renren-fast/src/main/resources/static/swagger/index.html new file mode 100644 index 0000000..200e5cf --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/index.html @@ -0,0 +1,107 @@ + + + + + + 接口文档 - 人人开源 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
    +
    + + diff --git a/renren-fast/src/main/resources/static/swagger/index.yaml b/renren-fast/src/main/resources/static/swagger/index.yaml new file mode 100644 index 0000000..58b7578 --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/index.yaml @@ -0,0 +1,1664 @@ +swagger: '2.0' +info: + description: renren-fast是一个轻量级的Java快速开发平台,能快速开发项目并交付【接私活利器】 + version: 1.0.0 + title: 人人快速开发平台 + +basePath: /renren-fast + +schemes: + - http + +#认证 +securityDefinitions: + api_key: + type: "apiKey" + name: "token" + in: "header" + +#定义接口数据 +paths: + /captcha.jpg: + get: + tags: + - 用户登录 + summary: 获取验证码 + produces: + - application/octet-stream + parameters: + - name: uuid + description: UUID + in: query + type: string + required: true + /sys/login: + post: + tags: + - 用户登录 + summary: 用户登录 + produces: + - application/json + parameters: + - name: body + description: 管理员对象 + in: body + type: string + schema: + $ref: '#/definitions/LoginForm' + required: true + responses: + '200': + schema: + $ref: '#/definitions/Login' + + /sys/user/list: + get: + tags: + - 管理员管理 + summary: 管理员列表 + produces: + - application/json + parameters: + - name: page + description: 页码 + in: query + type: integer + required: true + - name: limit + description: 每页条数 + in: query + type: integer + required: true + - name: sidx + description: 排序字段 + in: query + type: string + - name: order + description: 排序方式,如:asc、desc + in: query + type: string + - name: username + description: 用户名 + in: query + type: string + responses: + '200': + description: 返回管理员列表 + schema: + $ref: '#/definitions/SysUserEntityList' + /sys/user/info: + get: + tags: + - 管理员管理 + summary: 当前管理员信息 + produces: + - application/json + responses: + '200': + description: 返回当前管理员信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + user: + $ref: '#/definitions/SysUserEntity' + /sys/user/info/{userId}: + get: + tags: + - 管理员管理 + summary: 获取管理员信息 + produces: + - application/json + parameters: + - name: userId + description: 用户ID + in: path + type: integer + required: true + responses: + '200': + description: 返回管理员信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + user: + $ref: '#/definitions/SysUserEntity' + /sys/user/password: + post: + tags: + - 管理员管理 + summary: 修改密码 + produces: + - application/json + parameters: + - name: body + description: 管理员对象 + in: body + type: string + schema: + $ref: '#/definitions/PasswordForm' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/user/save: + post: + tags: + - 管理员管理 + summary: 添加管理员 + produces: + - application/json + parameters: + - name: body + description: 管理员对象 + in: body + type: string + schema: + $ref: '#/definitions/SysUserEntityEdit' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/user/update: + post: + tags: + - 管理员管理 + summary: 修改管理员 + produces: + - application/json + parameters: + - name: body + description: 管理员对象 + in: body + type: string + schema: + $ref: '#/definitions/SysUserEntityEdit' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/user/delete: + post: + tags: + - 管理员管理 + summary: 删除管理员 + produces: + - application/json + parameters: + - name: body + description: 用户ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + + /sys/role/list: + get: + tags: + - 角色管理 + summary: 角色列表 + produces: + - application/json + parameters: + - name: page + description: 页码 + in: query + type: integer + required: true + - name: limit + description: 每页条数 + in: query + type: integer + required: true + - name: sidx + description: 排序字段 + in: query + type: string + - name: order + description: 排序方式,如:asc、desc + in: query + type: string + - name: roleName + description: 角色名 + in: query + type: string + responses: + '200': + description: 返回角色列表 + schema: + $ref: '#/definitions/SysRoleEntityList' + /sys/role/select: + get: + tags: + - 角色管理 + summary: 当前账号角色列表 + description: 如果是超级管理员,则能查询所有的角色列表 + produces: + - application/json + responses: + '200': + description: 返回角色列表 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/SysRoleEntity' + /sys/role/info/{roleId}: + get: + tags: + - 角色管理 + summary: 获取角色信息 + produces: + - application/json + parameters: + - name: roleId + description: 角色ID + in: path + type: integer + required: true + responses: + '200': + description: 返回角色信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + role: + $ref: '#/definitions/SysRoleEntity' + /sys/role/save: + post: + tags: + - 角色管理 + summary: 添加角色 + produces: + - application/json + parameters: + - name: body + description: 角色对象 + in: body + type: string + schema: + $ref: '#/definitions/SysRoleEntityEdit' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/role/update: + post: + tags: + - 角色管理 + summary: 修改角色 + produces: + - application/json + parameters: + - name: body + description: 角色对象 + in: body + type: string + schema: + $ref: '#/definitions/SysRoleEntityEdit' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/role/delete: + post: + tags: + - 角色管理 + summary: 删除角色 + produces: + - application/json + parameters: + - name: body + description: 角色ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + + /sys/menu/nav: + get: + tags: + - 菜单管理 + summary: 导航菜单列表 + produces: + - application/json + responses: + '200': + description: 返回导航菜单列表 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + menuList: + description: 菜单列表 + type: array + items: + $ref: '#/definitions/SysMenuEntity' + permissions: + description: 权限列表 + type: array + items: + type: string + /sys/menu/list: + get: + tags: + - 菜单管理 + summary: 菜单列表 + produces: + - application/json + responses: + '200': + description: 返回菜单列表 + schema: + type: array + items: + $ref: '#/definitions/SysMenuEntity' + /sys/menu/select: + get: + tags: + - 菜单管理 + summary: 选择菜单 + description: 添加、修改菜单的时候,选择上级菜单接口 + produces: + - application/json + responses: + '200': + description: 返回菜单列表 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + menuList: + description: 菜单列表 + type: array + items: + $ref: '#/definitions/SysMenuEntity' + /sys/menu/info/{menuId}: + get: + tags: + - 菜单管理 + summary: 获取菜单信息 + produces: + - application/json + parameters: + - name: menuId + description: 菜单ID + in: path + type: integer + required: true + responses: + '200': + description: 返回菜单信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + menu: + description: 菜单信息 + $ref: '#/definitions/SysMenuEntity' + /sys/menu/save: + post: + tags: + - 菜单管理 + summary: 添加菜单 + produces: + - application/json + parameters: + - name: body + description: 菜单对象 + in: body + type: string + schema: + $ref: '#/definitions/SysMenuEntityEdit' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/menu/update: + post: + tags: + - 菜单管理 + summary: 修改菜单 + produces: + - application/json + parameters: + - name: body + description: 菜单对象 + in: body + type: string + schema: + $ref: '#/definitions/SysMenuEntityEdit' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/menu/delete/{menuId}: + post: + tags: + - 菜单管理 + summary: 删除菜单 + produces: + - application/json + parameters: + - name: menuId + description: 菜单ID + in: path + type: integer + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + + /sys/log/list: + get: + tags: + - 系统日志 + summary: 日志列表 + produces: + - application/json + parameters: + - name: page + description: 页码 + in: query + type: integer + required: true + - name: limit + description: 每页条数 + in: query + type: integer + required: true + - name: sidx + description: 排序字段 + in: query + type: string + - name: order + description: 排序方式,如:asc、desc + in: query + type: string + - name: key + description: 用户名或用户操作 + in: query + type: string + responses: + '200': + description: 返回日志列表 + schema: + $ref: '#/definitions/SysLogEntityList' + + /sys/config/list: + get: + tags: + - 参数管理 + summary: 参数列表 + produces: + - application/json + parameters: + - name: page + description: 页码 + in: query + type: integer + required: true + - name: limit + description: 每页条数 + in: query + type: integer + required: true + - name: sidx + description: 排序字段 + in: query + type: string + - name: order + description: 排序方式,如:asc、desc + in: query + type: string + - name: key + description: 参数名 + in: query + type: string + responses: + '200': + description: 返回参数列表 + schema: + $ref: '#/definitions/SysConfigEntityList' + /sys/config/info/{id}: + get: + tags: + - 参数管理 + summary: 获取参数信息 + produces: + - application/json + parameters: + - name: id + description: 参数ID + in: path + type: integer + required: true + responses: + '200': + description: 返回参数信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + config: + description: 返回参数信息 + $ref: '#/definitions/SysConfigEntity' + /sys/config/save: + post: + tags: + - 参数管理 + summary: 添加参数 + produces: + - application/json + parameters: + - name: body + description: 参数对象 + in: body + type: string + schema: + $ref: '#/definitions/SysConfigEntity' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/config/update: + post: + tags: + - 参数管理 + summary: 修改参数 + produces: + - application/json + parameters: + - name: body + description: 参数对象 + in: body + type: string + schema: + $ref: '#/definitions/SysConfigEntity' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/config/delete: + post: + tags: + - 参数管理 + summary: 删除参数 + produces: + - application/json + parameters: + - name: body + description: 参数ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + + /sys/oss/list: + get: + tags: + - 文件服务 + summary: 文件列表 + produces: + - application/json + parameters: + - name: page + description: 页码 + in: query + type: integer + required: true + - name: limit + description: 每页条数 + in: query + type: integer + required: true + - name: sidx + description: 排序字段 + in: query + type: string + - name: order + description: 排序方式,如:asc、desc + in: query + type: string + responses: + '200': + description: 返回文件列表 + schema: + $ref: '#/definitions/SysOssEntityList' + /sys/oss/config: + get: + tags: + - 文件服务 + summary: 云存储配置信息 + produces: + - application/json + responses: + '200': + description: 返回云存储配置信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + config: + description: 云存储配置信息 + $ref: '#/definitions/SysCloudStorageEntity' + /sys/oss/saveConfig: + post: + tags: + - 文件服务 + summary: 保存云存储配置信息 + produces: + - application/json + parameters: + - name: body + description: 参数对象 + in: body + type: string + schema: + $ref: '#/definitions/SysCloudStorageEntity' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/oss/upload: + post: + tags: + - 文件服务 + summary: 上传文件 + consumes: + - multipart/form-data + produces: + - application/json + parameters: + - name: file + description: 文件 + in: formData + type: file + required: true + responses: + '200': + description: 返回文件列表 + schema: + $ref: '#/definitions/FileUpload' + /sys/oss/delete: + post: + tags: + - 文件服务 + summary: 删除文件 + produces: + - application/json + parameters: + - name: body + description: 文件ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + + /sys/schedule/list: + get: + tags: + - 定时任务 + summary: 定时任务列表 + produces: + - application/json + parameters: + - name: page + description: 页码 + in: query + type: integer + required: true + - name: limit + description: 每页条数 + in: query + type: integer + required: true + - name: sidx + description: 排序字段 + in: query + type: string + - name: order + description: 排序方式,如:asc、desc + in: query + type: string + - name: beanName + description: spring bean名称 + in: query + type: string + responses: + '200': + description: 返回定时任务列表 + schema: + $ref: '#/definitions/ScheduleJobEntityList' + /sys/schedule/info/{jobId}: + get: + tags: + - 定时任务 + summary: 获取定时任务信息 + produces: + - application/json + parameters: + - name: jobId + description: 定时任务ID + in: path + type: integer + required: true + responses: + '200': + description: 返回定时任务信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + schedule: + description: 定时任务信息 + $ref: '#/definitions/ScheduleJobEntity' + /sys/schedule/save: + post: + tags: + - 定时任务 + summary: 添加定时任务 + produces: + - application/json + parameters: + - name: body + description: 定时任务对象 + in: body + type: string + schema: + $ref: '#/definitions/ScheduleJobEntity' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/schedule/update: + post: + tags: + - 定时任务 + summary: 修改定时任务 + produces: + - application/json + parameters: + - name: body + description: 定时任务对象 + in: body + type: string + schema: + $ref: '#/definitions/ScheduleJobEntity' + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/schedule/delete: + post: + tags: + - 定时任务 + summary: 删除定时任务 + produces: + - application/json + parameters: + - name: body + description: 定时任务ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/schedule/run: + post: + tags: + - 定时任务 + summary: 立即执行任务 + produces: + - application/json + parameters: + - name: body + description: 定时任务ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/schedule/pause: + post: + tags: + - 定时任务 + summary: 暂停定时任务 + produces: + - application/json + parameters: + - name: body + description: 定时任务ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + /sys/schedule/resume: + post: + tags: + - 定时任务 + summary: 恢复定时任务 + produces: + - application/json + parameters: + - name: body + description: 定时任务ID列表 + in: body + type: array + items: + type: integer + format: int64 + default: 0 + required: true + responses: + '200': + schema: + $ref: '#/definitions/R' + + /sys/scheduleLog/list: + get: + tags: + - 定时任务 + summary: 定时任务日志列表 + produces: + - application/json + parameters: + - name: page + description: 页码 + in: query + type: integer + required: true + - name: limit + description: 每页条数 + in: query + type: integer + required: true + - name: sidx + description: 排序字段 + in: query + type: string + - name: order + description: 排序方式,如:asc、desc + in: query + type: string + - name: beanName + description: spring bean名称 + in: query + type: string + responses: + '200': + description: 返回定时任务日志列表 + schema: + $ref: '#/definitions/ScheduleJobLogEntityList' + /sys/scheduleLog/info/{logId}: + get: + tags: + - 定时任务 + summary: 获取定时任务日志信息 + produces: + - application/json + parameters: + - name: logId + description: 日志ID + in: path + type: integer + required: true + responses: + '200': + description: 返回定时任务日志信息 + schema: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + schedule: + description: 定时任务日志信息 + $ref: '#/definitions/ScheduleJobLogEntity' + +#定义数据模型 +definitions: + R: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + msg: + description: 失败原因 + type: string + Login: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + token: + description: token + type: string + expire: + description: 过期时长 + type: integer + format: int32 + msg: + description: 失败原因 + type: string + LoginForm: + type: object + properties: + username: + description: 用户名 + type: string + password: + description: 密码 + type: string + captcha: + description: 验证码 + type: string + uuid: + description: UUID + type: string + PasswordForm: + type: object + properties: + password: + description: 原密码 + type: string + newPassword: + description: 新密码 + type: string + SysUserEntity: + type: object + properties: + userId: + description: 用户ID + type: integer + format: int64 + username: + description: 用户名 + type: string + password: + description: 密码 + type: string + email: + description: 邮箱 + type: string + mobile: + description: 手机号 + type: string + status: + description: 状态 0:禁用 1:正常 + type: integer + format: int32 + roleIdList: + description: 角色ID列表 + type: array + items: + type: integer + format: int64 + createUserId: + description: 创建者ID + type: integer + format: int64 + createTime: + description: 创建时间 + type: string + format: date-time + SysUserEntityList: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + page: + type: object + properties: + totalCount: + description: 总记录数 + type: integer + format: int32 + pageSize: + description: 每页记录数 + type: integer + format: int32 + totalPage: + description: 总页数 + type: integer + format: int32 + currPage: + description: 当前页数 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/SysUserEntity' + SysUserEntityEdit: + type: object + properties: + userId: + description: 用户ID + type: integer + format: int64 + username: + description: 用户名 + type: string + password: + description: 密码 + type: string + email: + description: 邮箱 + type: string + mobile: + description: 手机号 + type: string + status: + description: 状态 0:禁用 1:正常 + type: integer + format: int32 + roleIdList: + description: 角色ID列表 + type: array + items: + type: integer + format: int32 + + SysRoleEntity: + type: object + properties: + roleId: + description: 角色ID + type: integer + format: int64 + roleName: + description: 角色名称 + type: string + remark: + description: 备注 + type: string + menuIdList: + description: 菜单ID列表 + type: array + items: + type: integer + format: int64 + createUserId: + description: 创建者ID + type: integer + format: int64 + createTime: + description: 创建时间 + type: string + format: date-time + SysRoleEntityList: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + page: + type: object + properties: + totalCount: + description: 总记录数 + type: integer + format: int32 + pageSize: + description: 每页记录数 + type: integer + format: int32 + totalPage: + description: 总页数 + type: integer + format: int32 + currPage: + description: 当前页数 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/SysRoleEntity' + SysRoleEntityEdit: + type: object + properties: + roleId: + description: 角色ID + type: integer + format: int64 + roleName: + description: 角色名称 + type: string + remark: + description: 备注 + type: string + menuIdList: + description: 菜单ID列表 + type: array + items: + type: integer + format: int64 + + SysMenuEntity: + type: object + properties: + menuId: + description: 菜单ID + type: integer + format: int64 + name: + description: 菜单名称 + type: string + parentId: + description: 父菜单ID,一级菜单为0 + type: integer + format: int64 + parentName: + description: 父菜单名称 + type: string + url: + description: 菜单URL + type: string + perms: + description: 授权标识 + type: string + type: + description: 类型 0:目录 1:菜单 2:按钮 + type: integer + format: int32 + icon: + description: 菜单图标 + type: string + orderNum: + description: 排序 + type: integer + format: int32 + open: + description: 是否展开 true:展开 false:不展开 + type: boolean + format: int32 + SysMenuEntityEdit: + type: object + properties: + menuId: + description: 菜单ID + type: integer + format: int64 + name: + description: 菜单名称 + type: string + parentId: + description: 父菜单ID,一级菜单为0 + type: integer + format: int64 + url: + description: 菜单URL + type: string + perms: + description: 授权标识 + type: string + type: + description: 类型 0:目录 1:菜单 2:按钮 + type: integer + format: int32 + icon: + description: 菜单图标 + type: string + orderNum: + description: 排序 + type: integer + format: int32 + + SysLogEntity: + type: object + properties: + id: + description: 日志ID + type: integer + format: int64 + username: + description: 用户名 + type: string + operation: + description: 用户操作 + type: string + method: + description: 请求方法 + type: string + params: + description: 请求参数 + type: string + time: + description: 执行时长(毫秒) + type: integer + format: int64 + ip: + description: IP地址 + type: string + createTime: + description: 创建时间 + type: string + format: date-time + SysLogEntityList: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + page: + type: object + properties: + totalCount: + description: 总记录数 + type: integer + format: int32 + pageSize: + description: 每页记录数 + type: integer + format: int32 + totalPage: + description: 总页数 + type: integer + format: int32 + currPage: + description: 当前页数 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/SysLogEntity' + + SysConfigEntity: + type: object + properties: + id: + description: 参数ID + type: integer + format: int64 + key: + description: 参数名 + type: string + value: + description: 参数值 + type: string + remark: + description: 备注 + type: string + SysConfigEntityList: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + page: + type: object + properties: + totalCount: + description: 总记录数 + type: integer + format: int32 + pageSize: + description: 每页记录数 + type: integer + format: int32 + totalPage: + description: 总页数 + type: integer + format: int32 + currPage: + description: 当前页数 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/SysConfigEntity' + + SysOssEntity: + type: object + properties: + id: + description: ID + type: integer + format: int64 + url: + description: URL地址 + type: string + createTime: + description: 创建时间 + type: string + format: date-time + SysOssEntityList: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + page: + type: object + properties: + totalCount: + description: 总记录数 + type: integer + format: int32 + pageSize: + description: 每页记录数 + type: integer + format: int32 + totalPage: + description: 总页数 + type: integer + format: int32 + currPage: + description: 当前页数 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/SysOssEntity' + SysCloudStorageEntity: + type: object + properties: + type: + description: 类型 1:七牛 2:阿里云 3:腾讯云 + type: integer + format: int32 + qiniuDomain: + description: 七牛绑定的域名 + type: string + qiniuPrefix: + description: 七牛路径前缀 + type: string + qiniuAccessKey: + description: 七牛ACCESS_KEY + type: string + qiniuSecretKey: + description: 七牛SECRET_KEY + type: string + qiniuBucketName: + description: 七牛存储空间名 + type: string + aliyunDomain: + description: 阿里云绑定的域名 + type: string + aliyunPrefix: + description: 阿里云路径前缀 + type: string + aliyunEndPoint: + description: 阿里云EndPoint + type: string + aliyunAccessKeyId: + description: 阿里云AccessKeyId + type: string + aliyunAccessKeySecret: + description: 阿里云AccessKeySecret + type: string + aliyunBucketName: + description: 阿里云BucketName + type: string + qcloudDomain: + description: 腾讯云绑定的域名 + type: string + qcloudPrefix: + description: 腾讯云路径前缀 + type: string + qcloudAppId: + description: 腾讯云AppId + type: string + qcloudSecretId: + description: 腾讯云SecretId + type: string + qcloudSecretKey: + description: 腾讯云SecretKey + type: string + qcloudBucketName: + description: 腾讯云BucketName + type: string + qcloudRegion: + description: 腾讯云COS所属地区 + type: string + FileUpload: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + url: + description: 文件URL地址 + type: string + msg: + description: 失败原因 + type: string + + ScheduleJobEntity: + type: object + properties: + jobId: + description: 任务ID + type: integer + format: int64 + beanName: + description: spring bean名称 + type: string + methodName: + description: 方法名 + type: string + params: + description: 参数 + type: string + cronExpression: + description: cron表达式 + type: string + status: + description: 任务状态 0:正常 1:暂停 + type: integer + format: int32 + remark: + description: 备注 + type: string + createTime: + description: 创建时间 + type: string + format: date-time + ScheduleJobEntityList: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + page: + type: object + properties: + totalCount: + description: 总记录数 + type: integer + format: int32 + pageSize: + description: 每页记录数 + type: integer + format: int32 + totalPage: + description: 总页数 + type: integer + format: int32 + currPage: + description: 当前页数 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/ScheduleJobEntity' + + ScheduleJobLogEntity: + type: object + properties: + logId: + description: 日志id + type: integer + format: int64 + jobId: + description: 任务id + type: integer + format: int64 + beanName: + description: spring bean名称 + type: string + methodName: + description: 方法名 + type: string + params: + description: 参数 + type: string + status: + description: 任务状态 0:成功 1:失败 + type: integer + format: int32 + error: + description: 失败信息 + type: string + times: + description: 耗时(单位:毫秒) + type: integer + format: int32 + createTime: + description: 创建时间 + type: string + format: date-time + ScheduleJobLogEntityList: + type: object + properties: + code: + description: 状态码 0:成功 非0:失败 + type: integer + format: int32 + page: + type: object + properties: + totalCount: + description: 总记录数 + type: integer + format: int32 + pageSize: + description: 每页记录数 + type: integer + format: int32 + totalPage: + description: 总页数 + type: integer + format: int32 + currPage: + description: 当前页数 + type: integer + format: int32 + list: + type: array + items: + $ref: '#/definitions/ScheduleJobLogEntity' \ No newline at end of file diff --git a/renren-fast/src/main/resources/static/swagger/lang/en.js b/renren-fast/src/main/resources/static/swagger/lang/en.js new file mode 100644 index 0000000..9183136 --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/lang/en.js @@ -0,0 +1,56 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Warning: Deprecated", + "Implementation Notes":"Implementation Notes", + "Response Class":"Response Class", + "Status":"Status", + "Parameters":"Parameters", + "Parameter":"Parameter", + "Value":"Value", + "Description":"Description", + "Parameter Type":"Parameter Type", + "Data Type":"Data Type", + "Response Messages":"Response Messages", + "HTTP Status Code":"HTTP Status Code", + "Reason":"Reason", + "Response Model":"Response Model", + "Request URL":"Request URL", + "Response Body":"Response Body", + "Response Code":"Response Code", + "Response Headers":"Response Headers", + "Hide Response":"Hide Response", + "Headers":"Headers", + "Try it out!":"Try it out!", + "Show/Hide":"Show/Hide", + "List Operations":"List Operations", + "Expand Operations":"Expand Operations", + "Raw":"Raw", + "can't parse JSON. Raw result":"can't parse JSON. Raw result", + "Example Value":"Example Value", + "Model Schema":"Model Schema", + "Model":"Model", + "Click to set as parameter value":"Click to set as parameter value", + "apply":"apply", + "Username":"Username", + "Password":"Password", + "Terms of service":"Terms of service", + "Created by":"Created by", + "See more at":"See more at", + "Contact the developer":"Contact the developer", + "api version":"api version", + "Response Content Type":"Response Content Type", + "Parameter content type:":"Parameter content type:", + "fetching resource":"fetching resource", + "fetching resource list":"fetching resource list", + "Explore":"Explore", + "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", + "Please specify the protocol for":"Please specify the protocol for", + "Can't read swagger JSON from":"Can't read swagger JSON from", + "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", + "Unable to read api":"Unable to read api", + "from path":"from path", + "server returned":"server returned" +}); diff --git a/renren-fast/src/main/resources/static/swagger/lang/translator.js b/renren-fast/src/main/resources/static/swagger/lang/translator.js new file mode 100644 index 0000000..ffb879f --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/lang/translator.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * Translator for documentation pages. + * + * To enable translation you should include one of language-files in your index.html + * after . + * For example - + * + * If you wish to translate some new texts you should do two things: + * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too. + * 2. Mark that text it templates this way New Phrase or . + * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate. + * + */ +window.SwaggerTranslator = { + + _words:[], + + translate: function(sel) { + var $this = this; + sel = sel || '[data-sw-translate]'; + + $(sel).each(function() { + $(this).html($this._tryTranslate($(this).html())); + + $(this).val($this._tryTranslate($(this).val())); + $(this).attr('title', $this._tryTranslate($(this).attr('title'))); + }); + }, + + _tryTranslate: function(word) { + return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; + }, + + learn: function(wordsMap) { + this._words = wordsMap; + } +}; diff --git a/renren-fast/src/main/resources/static/swagger/lang/zh-cn.js b/renren-fast/src/main/resources/static/swagger/lang/zh-cn.js new file mode 100644 index 0000000..c7f55b4 --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/lang/zh-cn.js @@ -0,0 +1,56 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"警告:已过时", + "Implementation Notes":"接口备注", + "Response Class":"响应类", + "Status":"状态", + "Parameters":"参数", + "Parameter":"参数", + "Value":"值", + "Description":"描述", + "Parameter Type":"参数类型", + "Data Type":"数据类型", + "Response Messages":"响应消息", + "HTTP Status Code":"HTTP状态码", + "Reason":"原因", + "Response Model":"响应模型", + "Request URL":"请求URL", + "Response Body":"响应体", + "Response Code":"响应码", + "Response Headers":"响应头", + "Hide Response":"隐藏响应", + "Headers":"头", + "Try it out!":"试一下!", + "Show/Hide":"显示/隐藏", + "List Operations":"显示操作", + "Expand Operations":"展开操作", + "Raw":"原始", + "can't parse JSON. Raw result":"无法解析JSON. 原始结果", + "Example Value":"示例", + "Click to set as parameter value":"点击设置参数", + "Model Schema":"模型架构", + "Model":"模型", + "apply":"应用", + "Username":"用户名", + "Password":"密码", + "Terms of service":"服务条款", + "Created by":"创建者", + "See more at":"查看更多:", + "Contact the developer":"联系开发者", + "api version":"api版本", + "Response Content Type":"响应类型", + "Parameter content type:":"参数类型:", + "fetching resource":"正在获取资源", + "fetching resource list":"正在获取资源列表", + "Explore":"浏览", + "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。", + "Please specify the protocol for":"请指定协议:", + "Can't read swagger JSON from":"无法读取swagger JSON于", + "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI", + "Unable to read api":"无法读取api", + "from path":"从路径", + "server returned":"服务器返回" +}); diff --git a/renren-fast/src/main/resources/static/swagger/lib/backbone-min.js b/renren-fast/src/main/resources/static/swagger/lib/backbone-min.js new file mode 100644 index 0000000..8eff02e --- /dev/null +++ b/renren-fast/src/main/resources/static/swagger/lib/backbone-min.js @@ -0,0 +1 @@ +!function(t,e){if("function"==typeof define&&define.amd)define(["underscore","jquery","exports"],function(i,n,s){t.Backbone=e(t,s,i,n)});else if("undefined"!=typeof exports){var i=require("underscore");e(t,exports,i)}else t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}(this,function(t,e,i,n){var s=t.Backbone,r=[],a=(r.push,r.slice);r.splice;e.VERSION="1.1.2",e.$=n,e.noConflict=function(){return t.Backbone=s,this},e.emulateHTTP=!1,e.emulateJSON=!1;var o=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var n=this._events[t]||(this._events[t]=[]);return n.push({callback:e,context:i,ctx:i||this}),this},once:function(t,e,n){if(!c(this,"once",t,[e,n])||!e)return this;var s=this,r=i.once(function(){s.off(t,r),e.apply(this,arguments)});return r._callback=e,this.on(t,r,n)},off:function(t,e,n){var s,r,a,o,h,u,l,d;if(!this._events||!c(this,"off",t,[e,n]))return this;if(!t&&!e&&!n)return this._events=void 0,this;for(o=t?[t]:i.keys(this._events),h=0,u=o.length;h").attr(t);this.setElement(n,!1)}}}),e.sync=function(t,n,s){var r=E[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:r,dataType:"json"};if(s.url||(a.url=i.result(n,"url")||j()),null!=s.data||!n||"create"!==t&&"update"!==t&&"patch"!==t||(a.contentType="application/json",a.data=JSON.stringify(s.attrs||n.toJSON(s))),s.emulateJSON&&(a.contentType="application/x-www-form-urlencoded",a.data=a.data?{model:a.data}:{}),s.emulateHTTP&&("PUT"===r||"DELETE"===r||"PATCH"===r)){a.type="POST",s.emulateJSON&&(a.data._method=r);var o=s.beforeSend;s.beforeSend=function(t){if(t.setRequestHeader("X-HTTP-Method-Override",r),o)return o.apply(this,arguments)}}"GET"===a.type||s.emulateJSON||(a.processData=!1),"PATCH"===a.type&&x&&(a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")});var h=s.xhr=e.ajax(i.extend(a,s));return n.trigger("request",n,h,s),h};var x=!("undefined"==typeof window||!window.ActiveXObject||window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent),E={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var k=e.Router=function(t){t||(t={}),t.routes&&(this.routes=t.routes),this._bindRoutes(),this.initialize.apply(this,arguments)},T=/\((.*?)\)/g,$=/(\(\?)?:\w+/g,S=/\*\w+/g,H=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend(k.prototype,o,{initialize:function(){},route:function(t,n,s){i.isRegExp(t)||(t=this._routeToRegExp(t)),i.isFunction(n)&&(s=n,n=""),s||(s=this[n]);var r=this;return e.history.route(t,function(i){var a=r._extractParameters(t,i);r.execute(s,a),r.trigger.apply(r,["route:"+n].concat(a)),r.trigger("route",n,a),e.history.trigger("route",r,n,a)}),this},execute:function(t,e){t&&t.apply(this,e)},navigate:function(t,i){return e.history.navigate(t,i),this},_bindRoutes:function(){if(this.routes){this.routes=i.result(this,"routes");for(var t,e=i.keys(this.routes);null!=(t=e.pop());)this.route(t,this.routes[t])}},_routeToRegExp:function(t){return t=t.replace(H,"\\$&").replace(T,"(?:$1)?").replace($,function(t,e){return e?t:"([^/?]+)"}).replace(S,"([^?]*?)"),new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var n=t.exec(e).slice(1);return i.map(n,function(t,e){return e===n.length-1?t||null:t?decodeURIComponent(t):null})}});var A=e.History=function(){this.handlers=[],i.bindAll(this,"checkUrl"),"undefined"!=typeof window&&(this.location=window.location,this.history=window.history)},I=/^[#\/]|\s+$/g,N=/^\/+|\/+$/g,R=/msie [\w.]+/,O=/\/$/,P=/#.*$/;A.started=!1,i.extend(A.prototype,o,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(null==t)if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(O,"");t.indexOf(i)||(t=t.slice(i.length))}else t=this.getHash();return t.replace(I,"")},start:function(t){if(A.started)throw new Error("Backbone.history has already been started");A.started=!0,this.options=i.extend({root:"/"},this.options,t),this.root=this.options.root,this._wantsHashChange=this.options.hashChange!==!1,this._wantsPushState=!!this.options.pushState,this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var n=this.getFragment(),s=document.documentMode,r=R.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);if(this.root=("/"+this.root+"/").replace(N,"/"),r&&this._wantsHashChange){var a=e.$('';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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 params){ + PageUtils page = ${classname}Service.queryPage(params); + + return R.ok().put("page", page); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{${pk.attrname}}") + @RequiresPermissions("${moduleName}:${pathName}:info") + public R info(@PathVariable("${pk.attrname}") ${pk.attrType} ${pk.attrname}){ + ${className}Entity ${classname} = ${classname}Service.getById(${pk.attrname}); + + return R.ok().put("${classname}", ${classname}); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("${moduleName}:${pathName}:save") + public R save(@RequestBody ${className}Entity ${classname}){ + ${classname}Service.save(${classname}); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("${moduleName}:${pathName}:update") + public R update(@RequestBody ${className}Entity ${classname}){ + ${classname}Service.updateById(${classname}); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("${moduleName}:${pathName}:delete") + public R delete(@RequestBody ${pk.attrType}[] ${pk.attrname}s){ + ${classname}Service.removeByIds(Arrays.asList(${pk.attrname}s)); + + return R.ok(); + } + +} 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..935a2fc --- /dev/null +++ b/renren-generator/src/main/resources/template/Dao.java.vm @@ -0,0 +1,17 @@ +package ${package}.${moduleName}.dao; + +import ${package}.${moduleName}.entity.${className}Entity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +@Mapper +public interface ${className}Dao extends BaseMapper<${className}Entity> { + +} 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..b742fe9 --- /dev/null +++ b/renren-generator/src/main/resources/template/Dao.xml.vm @@ -0,0 +1,14 @@ + + + + + + + +#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..362cfa9 --- /dev/null +++ b/renren-generator/src/main/resources/template/Entity.java.vm @@ -0,0 +1,35 @@ +package ${package}.${moduleName}.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +#if(${hasBigDecimal}) +import java.math.BigDecimal; +#end +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +@Data +@TableName("${tableName}") +public class ${className}Entity implements Serializable { + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) + /** + * $column.comments + */ + #if($column.columnName == $pk.columnName) +@TableId + #end +private $column.attrType $column.attrname; +#end + +} diff --git a/renren-generator/src/main/resources/template/MongoChildrenEntity.java.vm b/renren-generator/src/main/resources/template/MongoChildrenEntity.java.vm new file mode 100644 index 0000000..14a7009 --- /dev/null +++ b/renren-generator/src/main/resources/template/MongoChildrenEntity.java.vm @@ -0,0 +1,29 @@ +package ${package}.${moduleName}.entity; + + +#if(${hasList}) +import java.util.List; +#end + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.annotation.Id; + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +@Data +public class ${className}InnerEntity { + + +#foreach ($column in $columns) +private #if($column.extra == "array")List<#end$column.attrType#if($column.extra == "array")>#end $column.attrname; +#end + +} diff --git a/renren-generator/src/main/resources/template/MongoEntity.java.vm b/renren-generator/src/main/resources/template/MongoEntity.java.vm new file mode 100644 index 0000000..c76aacd --- /dev/null +++ b/renren-generator/src/main/resources/template/MongoEntity.java.vm @@ -0,0 +1,36 @@ +package ${package}.${moduleName}.entity; + + +#if(${hasBigDecimal}) +import java.math.BigDecimal; +#end +#if(${hasList}) +import java.util.List; +#end + +import java.io.Serializable; +import java.util.Date; +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.annotation.Id; + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +@Data +@Document(collection = "${tableName}") +public class ${className}Entity implements Serializable { + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) + #if($column.columnName == "id") +@Id + #end +private #if($column.extra == "array")List<#end$column.attrType#if($column.extra == "array")>#end $column.attrname; +#end + +} 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..2bac39b --- /dev/null +++ b/renren-generator/src/main/resources/template/Service.java.vm @@ -0,0 +1,20 @@ +package ${package}.${moduleName}.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import ${mainPath}.common.utils.PageUtils; +import ${package}.${moduleName}.entity.${className}Entity; + +import java.util.Map; + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +public interface ${className}Service extends IService<${className}Entity> { + + PageUtils queryPage(Map params); +} + 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..cc1a938 --- /dev/null +++ b/renren-generator/src/main/resources/template/ServiceImpl.java.vm @@ -0,0 +1,29 @@ +package ${package}.${moduleName}.service.impl; + +import org.springframework.stereotype.Service; +import java.util.Map; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import ${mainPath}.common.utils.PageUtils; +import ${mainPath}.common.utils.Query; + +import ${package}.${moduleName}.dao.${className}Dao; +import ${package}.${moduleName}.entity.${className}Entity; +import ${package}.${moduleName}.service.${className}Service; + + +@Service("${classname}Service") +public class ${className}ServiceImpl extends ServiceImpl<${className}Dao, ${className}Entity> implements ${className}Service { + + @Override + public PageUtils queryPage(Map params) { + IPage<${className}Entity> page = this.page( + new Query<${className}Entity>().getPage(params), + new QueryWrapper<${className}Entity>() + ); + + return new PageUtils(page); + } + +} \ 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..d19de2f --- /dev/null +++ b/renren-generator/src/main/resources/template/add-or-update.vue.vm @@ -0,0 +1,109 @@ + + + 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..1246655 --- /dev/null +++ b/renren-generator/src/main/resources/template/index.vue.vm @@ -0,0 +1,159 @@ + + + diff --git a/renren-generator/src/main/resources/template/menu.sql.vm b/renren-generator/src/main/resources/template/menu.sql.vm new file mode 100644 index 0000000..2b9495a --- /dev/null +++ b/renren-generator/src/main/resources/template/menu.sql.vm @@ -0,0 +1,16 @@ +-- 菜单SQL +INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + VALUES ('1', '${comments}', '${moduleName}/${pathName}', NULL, '1', 'config', '6'); + +-- 按钮父菜单ID +set @parentId = @@identity; + +-- 菜单对应按钮SQL +INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + SELECT @parentId, '查看', null, '${moduleName}:${pathName}:list,${moduleName}:${pathName}:info', '2', null, '6'; +INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + SELECT @parentId, '新增', null, '${moduleName}:${pathName}:save', '2', null, '6'; +INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + SELECT @parentId, '修改', null, '${moduleName}:${pathName}:update', '2', null, '6'; +INSERT INTO `sys_menu` (`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + SELECT @parentId, '删除', null, '${moduleName}:${pathName}:delete', '2', null, '6'; 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..f03ffdb --- /dev/null +++ b/renren-generator/src/main/resources/views/index.html @@ -0,0 +1,110 @@ + + + + + + 人人代码生成器 + + + + + + + + + + + + +
    +
    + + + +
    + + + + + + + +
    + +
    + +
    + + +
    + +
    + +
    + + +
    + + Copyright © 2017 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..9cca279 --- /dev/null +++ b/renren-generator/src/main/resources/views/main.html @@ -0,0 +1,29 @@ + + + + + + 欢迎页 + + + + +
    +
    基本信息
    +
    +

       获取帮助

    + + +

       官方QQ群

    +
      +
    • 高级群:324780204(大牛云集,跟大牛学习新技能)
    • +
    • 普通群:145799952(学习交流,互相解答各种疑问)
    • +
    +
    +
    + + \ No newline at end of file diff --git a/renren-generator/src/test/java/io/renren/RenrenApplicationTests.java b/renren-generator/src/test/java/io/renren/RenrenApplicationTests.java new file mode 100644 index 0000000..bacacc8 --- /dev/null +++ b/renren-generator/src/test/java/io/renren/RenrenApplicationTests.java @@ -0,0 +1,16 @@ +package io.renren; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class RenrenApplicationTests { + + @Test + public void contextLoads() { + } + +}