Repository: qiurunze123/miaosha Branch: master Commit: e58017658e54 Files: 866 Total size: 9.9 MB Directory structure: gitextract_75nft3s6/ ├── .gitattributes ├── .gitignore ├── CHANGELOG.md ├── README.md ├── docs/ │ ├── code-criterion.md │ ├── code-rpc.md │ ├── code-solve.md │ ├── dubbo-admin.md │ ├── dubbo-zk.md │ ├── fenbushi-tcc.md │ ├── fenbushi.md │ ├── jemter-solve.md │ ├── jvm-goods.md │ ├── linux.md │ ├── maven-wrapper.md │ ├── mybatis-code.md │ ├── mysql-2.md │ ├── mysql-3.md │ ├── mysql-master-slave.md │ ├── mysql-mvcc.md │ ├── mysql.md │ ├── netty.md │ ├── ngnix-good.md │ ├── old.md │ ├── redis-good.md │ ├── redis-lua.md │ └── tomcat-good.md ├── miaosha-admin/ │ ├── .gitignore │ ├── miaosha-admin-api/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── com/ │ │ └── geekq/ │ │ └── admin/ │ │ ├── entity/ │ │ │ ├── Account.java │ │ │ ├── BaseDomain.java │ │ │ ├── IpLog.java │ │ │ ├── Logininfo.java │ │ │ ├── SystemDictionary.java │ │ │ ├── SystemDictionaryItem.java │ │ │ └── Userinfo.java │ │ ├── pojo/ │ │ │ ├── Orders.java │ │ │ └── OrdersExample.java │ │ ├── query/ │ │ │ ├── IpLogQueryObject.java │ │ │ ├── PageResult.java │ │ │ ├── QueryObject.java │ │ │ └── SystemDictionaryQueryObject.java │ │ └── service/ │ │ ├── IAccountService.java │ │ ├── IIpLogService.java │ │ ├── ILogininfoService.java │ │ ├── ISystemDictionaryService.java │ │ ├── IUserService.java │ │ ├── OrdersService.java │ │ └── RedisCacheStorageService.java │ ├── miaosha-admin-common/ │ │ ├── .gitignore │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── com/ │ │ └── geekq/ │ │ └── common/ │ │ ├── enums/ │ │ │ ├── Constants.java │ │ │ ├── MessageStatus.java │ │ │ ├── OrderStatusEnum.java │ │ │ ├── ResultStatus.java │ │ │ ├── SexEnum.java │ │ │ └── YesOrNo.java │ │ ├── utils/ │ │ │ ├── Constanst.java │ │ │ ├── DBContextUtil.java │ │ │ ├── DateUtil.java │ │ │ ├── JsonUtils.java │ │ │ ├── SnowflakeIdWorker.java │ │ │ ├── ValidatorUtil.java │ │ │ ├── md5/ │ │ │ │ └── MD5Utils.java │ │ │ ├── numcal/ │ │ │ │ ├── BidConst.java │ │ │ │ ├── BitStatesUtils.java │ │ │ │ ├── CalculateUtil.java │ │ │ │ └── DecimalFormatUtil.java │ │ │ └── resultbean/ │ │ │ ├── AbstractResult.java │ │ │ ├── ResultGeekQ.java │ │ │ └── ResultJSON.java │ │ ├── validator/ │ │ │ ├── MobileCheck.java │ │ │ └── MobileValidator.java │ │ └── vo/ │ │ └── LoginVo.java │ ├── miaosha-admin-service/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── geekq/ │ │ │ └── admin/ │ │ │ ├── mapper/ │ │ │ │ ├── AccountMapper.java │ │ │ │ ├── AccountMapper.xml │ │ │ │ ├── IpLogMapper.java │ │ │ │ ├── IpLogMapper.xml │ │ │ │ ├── LogininfoMapper.java │ │ │ │ ├── LogininfoMapper.xml │ │ │ │ ├── OrdersMapper.java │ │ │ │ ├── OrdersMapper.xml │ │ │ │ ├── SystemDictionaryItemMapper.java │ │ │ │ ├── SystemDictionaryItemMapper.xml │ │ │ │ ├── SystemDictionaryMapper.java │ │ │ │ ├── SystemDictionaryMapper.xml │ │ │ │ ├── UserinfoMapper.java │ │ │ │ └── UserinfoMapper.xml │ │ │ ├── redis/ │ │ │ │ └── RedisClient.java │ │ │ ├── service/ │ │ │ │ └── impl/ │ │ │ │ ├── AccountServiceImpl.java │ │ │ │ ├── IpLogServiceImpl.java │ │ │ │ ├── LogininfoServiceImpl.java │ │ │ │ ├── OrdersServiceImpl.java │ │ │ │ ├── RedisCache.java │ │ │ │ ├── RedisCacheStorageServiceImpl.java │ │ │ │ ├── SystemDictionaryServiceImpl.java │ │ │ │ ├── SystemDictionaryUtil.java │ │ │ │ └── UserServiceImpl.java │ │ │ └── utils/ │ │ │ └── UserContext.java │ │ ├── resources/ │ │ │ ├── dubbo/ │ │ │ │ └── dubbo.xsd │ │ │ ├── log4j.properties │ │ │ ├── mybatis/ │ │ │ │ └── SqlMapConfig.xml │ │ │ ├── resource/ │ │ │ │ ├── db.properties │ │ │ │ └── redis.properties │ │ │ └── spring/ │ │ │ ├── applicationContext-dao.xml │ │ │ ├── applicationContext-dubbo-provider.xml │ │ │ ├── applicationContext-redis.xml │ │ │ ├── applicationContext-service.xml │ │ │ ├── applicationContext-transaction.xml │ │ │ └── spring-context.xml │ │ └── webapp/ │ │ └── WEB-INF/ │ │ └── web.xml │ ├── miaosha-admin-web/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── geekq/ │ │ │ └── web/ │ │ │ ├── controller/ │ │ │ │ ├── BaseController.java │ │ │ │ ├── LoginController.java │ │ │ │ ├── PayController.java │ │ │ │ ├── PersonController.java │ │ │ │ └── RegisterController.java │ │ │ ├── interceptor/ │ │ │ │ ├── AddGlobalUtilInterceptor.java │ │ │ │ ├── LoginInterceptor.java │ │ │ │ └── RequiredLogin.java │ │ │ └── service/ │ │ │ ├── CulsterService.java │ │ │ └── impl/ │ │ │ └── CulsterServiceImpl.java │ │ ├── resources/ │ │ │ ├── log4j.properties │ │ │ └── spring/ │ │ │ ├── applicationContext-dubbo-consumer.xml │ │ │ ├── applicationContext-service.xml │ │ │ └── springmvc.xml │ │ └── webapp/ │ │ ├── WEB-INF/ │ │ │ ├── views/ │ │ │ │ ├── bankInfo.ftl │ │ │ │ ├── bankInfo_result.ftl │ │ │ │ ├── bidRequest_list.ftl │ │ │ │ ├── bid_list.ftl │ │ │ │ ├── borrow.ftl │ │ │ │ ├── borrow_apply.ftl │ │ │ │ ├── borrow_apply_result.ftl │ │ │ │ ├── borrow_info.ftl │ │ │ │ ├── checkmail_result.ftl │ │ │ │ ├── common/ │ │ │ │ │ ├── footer-tpl.ftl │ │ │ │ │ ├── head-tpl.ftl │ │ │ │ │ ├── leftmenu-tpl.ftl │ │ │ │ │ ├── links-tpl.ftl │ │ │ │ │ ├── loadSystemDictionary-macro.ftl │ │ │ │ │ └── navbar-tpl.ftl │ │ │ │ ├── invest.ftl │ │ │ │ ├── invest_list.ftl │ │ │ │ ├── iplog_list.ftl │ │ │ │ ├── main.ftl │ │ │ │ ├── moneyWithdraw_apply.ftl │ │ │ │ ├── personal.ftl │ │ │ │ ├── realAuth.ftl │ │ │ │ ├── realAuth_result.ftl │ │ │ │ ├── recharge.ftl │ │ │ │ ├── recharge_list.ftl │ │ │ │ ├── returnmoney_list.ftl │ │ │ │ ├── userFiles.ftl │ │ │ │ ├── userFiles_commit.ftl │ │ │ │ └── userInfo.ftl │ │ │ └── web.xml │ │ ├── bootstrap.html │ │ ├── borrow.html │ │ ├── css/ │ │ │ ├── account.css │ │ │ ├── bank.css │ │ │ └── core.css │ │ ├── index.html │ │ ├── js/ │ │ │ ├── My97DatePicker/ │ │ │ │ ├── My97DatePicker.htm │ │ │ │ ├── WdatePicker.js │ │ │ │ ├── calendar.js │ │ │ │ ├── config.js │ │ │ │ ├── lang/ │ │ │ │ │ ├── en.js │ │ │ │ │ ├── zh-cn.js │ │ │ │ │ └── zh-tw.js │ │ │ │ └── skin/ │ │ │ │ ├── WdatePicker.css │ │ │ │ ├── default/ │ │ │ │ │ └── datepicker.css │ │ │ │ └── whyGreen/ │ │ │ │ └── datepicker.css │ │ │ ├── bank.js │ │ │ ├── bootstrap-3.3.2-dist/ │ │ │ │ ├── css/ │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ └── bootstrap.css │ │ │ │ └── js/ │ │ │ │ ├── bootstrap.js │ │ │ │ └── npm.js │ │ │ ├── jquery/ │ │ │ │ └── jquery-2.1.3.js │ │ │ ├── metisMenu/ │ │ │ │ ├── metisMenu.css │ │ │ │ └── metisMenu.js │ │ │ ├── plugins/ │ │ │ │ ├── datetimepicker/ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .travis.yml │ │ │ │ │ ├── README.md │ │ │ │ │ ├── css/ │ │ │ │ │ │ └── bootstrap-datetimepicker.css │ │ │ │ │ ├── js/ │ │ │ │ │ │ ├── bootstrap-datetimepicker.js │ │ │ │ │ │ └── locales/ │ │ │ │ │ │ └── bootstrap-datetimepicker.zh-CN.js │ │ │ │ │ ├── sample in bootstrap v2/ │ │ │ │ │ │ ├── bootstrap/ │ │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ │ └── bootstrap.css │ │ │ │ │ │ │ └── js/ │ │ │ │ │ │ │ └── bootstrap.js │ │ │ │ │ │ └── index.html │ │ │ │ │ └── sample in bootstrap v3/ │ │ │ │ │ ├── bootstrap/ │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ │ │ └── bootstrap.css │ │ │ │ │ │ └── js/ │ │ │ │ │ │ └── bootstrap.js │ │ │ │ │ └── index.html │ │ │ │ ├── flipcountdown/ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── MIT-LICENSE.txt │ │ │ │ │ ├── README.md │ │ │ │ │ ├── bower.json │ │ │ │ │ ├── flipcountdown.jquery.json │ │ │ │ │ ├── img/ │ │ │ │ │ │ ├── am-pm-1.psd │ │ │ │ │ │ ├── digit-lg-dark.psd │ │ │ │ │ │ └── digit-lg.psd │ │ │ │ │ ├── index.html │ │ │ │ │ ├── jquery.flipcountdown.css │ │ │ │ │ ├── jquery.flipcountdown.js │ │ │ │ │ └── package.json │ │ │ │ ├── jquery-validation/ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .travis.yml │ │ │ │ │ ├── demo/ │ │ │ │ │ │ ├── ajaxSubmit-intergration-demo.html │ │ │ │ │ │ ├── captcha/ │ │ │ │ │ │ │ ├── captcha.js │ │ │ │ │ │ │ ├── image_req.php │ │ │ │ │ │ │ ├── images/ │ │ │ │ │ │ │ │ ├── .htaccess │ │ │ │ │ │ │ │ └── image.php │ │ │ │ │ │ │ ├── index.php │ │ │ │ │ │ │ ├── newsession.php │ │ │ │ │ │ │ ├── process.php │ │ │ │ │ │ │ ├── rand.php │ │ │ │ │ │ │ └── style.css │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ ├── chili.css │ │ │ │ │ │ │ ├── cmxform.css │ │ │ │ │ │ │ ├── cmxformTemplate.css │ │ │ │ │ │ │ ├── core.css │ │ │ │ │ │ │ ├── reset.css │ │ │ │ │ │ │ └── screen.css │ │ │ │ │ │ ├── custom-messages-data-demo.html │ │ │ │ │ │ ├── custom-methods-demo.html │ │ │ │ │ │ ├── dynamic-totals.html │ │ │ │ │ │ ├── errorcontainer-demo.html │ │ │ │ │ │ ├── file_input.html │ │ │ │ │ │ ├── form.php │ │ │ │ │ │ ├── form.phps │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── jquerymobile.html │ │ │ │ │ │ ├── js/ │ │ │ │ │ │ │ └── chili-1.7.pack.js │ │ │ │ │ │ ├── login/ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── screen.css │ │ │ │ │ │ ├── marketo/ │ │ │ │ │ │ │ ├── emails.php │ │ │ │ │ │ │ ├── emails.phps │ │ │ │ │ │ │ ├── ie6.css │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── jquery.maskedinput.js │ │ │ │ │ │ │ ├── mktSignup.js │ │ │ │ │ │ │ ├── step2.htm │ │ │ │ │ │ │ └── stylesheet.css │ │ │ │ │ │ ├── milk/ │ │ │ │ │ │ │ ├── emails.php │ │ │ │ │ │ │ ├── emails.phps │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── milk.css │ │ │ │ │ │ │ ├── users.php │ │ │ │ │ │ │ └── users.phps │ │ │ │ │ │ ├── multipart/ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── js/ │ │ │ │ │ │ │ │ ├── jquery.maskedinput-1.0.js │ │ │ │ │ │ │ │ ├── ui.accordion.js │ │ │ │ │ │ │ │ └── ui.core.js │ │ │ │ │ │ │ └── style.css │ │ │ │ │ │ ├── radio-checkbox-select-demo.html │ │ │ │ │ │ ├── tabs/ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── themerollered.html │ │ │ │ │ │ └── tinymce/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── themes/ │ │ │ │ │ │ │ └── simple/ │ │ │ │ │ │ │ ├── editor_template.js │ │ │ │ │ │ │ ├── langs/ │ │ │ │ │ │ │ │ └── en.js │ │ │ │ │ │ │ └── skins/ │ │ │ │ │ │ │ └── default/ │ │ │ │ │ │ │ └── ui.css │ │ │ │ │ │ └── tiny_mce.js │ │ │ │ │ ├── jquery.validate.js │ │ │ │ │ ├── lib/ │ │ │ │ │ │ ├── jquery-1.6.4.js │ │ │ │ │ │ ├── jquery-1.7.2.js │ │ │ │ │ │ ├── jquery-1.8.3.js │ │ │ │ │ │ ├── jquery-1.9.0.js │ │ │ │ │ │ ├── jquery.form.js │ │ │ │ │ │ ├── jquery.js │ │ │ │ │ │ └── jquery.mockjax.js │ │ │ │ │ └── localization/ │ │ │ │ │ └── messages_zh.js │ │ │ │ ├── jquery.form.js │ │ │ │ ├── jquery.twbsPagination.js │ │ │ │ └── uploadify/ │ │ │ │ ├── jquery.uploadify.js │ │ │ │ └── uploadify.swf │ │ │ └── plugins-override.js │ │ ├── jsp/ │ │ │ └── index.jsp │ │ ├── login.html │ │ └── register.html │ └── pom.xml ├── miaosha-order/ │ ├── .gitignore │ ├── README.md │ ├── miaosha-order-api/ │ │ ├── .gitignore │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── com/ │ │ └── geekq/ │ │ └── api/ │ │ ├── entity/ │ │ │ ├── Goods.java │ │ │ ├── GoodsVoOrder.java │ │ │ └── MiaoshaGoods.java │ │ ├── service/ │ │ │ ├── GoodsService.java │ │ │ └── GoodsServiceMock.java │ │ └── utils/ │ │ ├── AbstractResultOrder.java │ │ ├── ResultGeekQOrder.java │ │ └── ResultStatusOrder.java │ ├── miaosha-order-provider/ │ │ ├── .gitignore │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── geekq/ │ │ │ │ └── provider/ │ │ │ │ ├── DubboProviderApplication.java │ │ │ │ ├── mapper/ │ │ │ │ │ ├── GoodsMapper.java │ │ │ │ │ └── GoodsMapper.xml │ │ │ │ └── service/ │ │ │ │ └── impl/ │ │ │ │ ├── GoodsGroupServiceImpl.java │ │ │ │ └── GoodsServiceImpl.java │ │ │ └── resources/ │ │ │ ├── application.properties │ │ │ └── provider.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── geekq/ │ │ └── provider/ │ │ └── DubboProviderApplicationTests.java │ ├── mvnw │ ├── mvnw.cmd │ └── pom.xml ├── miaosha-rpc/ │ ├── .gitignore │ ├── dubbo-api/ │ │ ├── pom.xml │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ ├── com/ │ │ │ │ └── geekq/ │ │ │ │ └── dubbo/ │ │ │ │ └── springboot/ │ │ │ │ ├── CapAccountTradeOrderService.java │ │ │ │ └── ServiceAPI.java │ │ │ └── dto/ │ │ │ └── CapitalTradeOrderDto.java │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── geekq/ │ │ └── dubbo/ │ │ └── springboot/ │ │ └── AppTest.java │ ├── dubbo-consumer/ │ │ ├── .gitignore │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── geekq/ │ │ │ └── dubbo/ │ │ │ └── springboot/ │ │ │ └── consumer/ │ │ │ ├── ConsumerApplication.java │ │ │ ├── config/ │ │ │ │ └── TCCConfig.java │ │ │ ├── quickstart/ │ │ │ │ └── QuickstartConsumer.java │ │ │ └── transaction/ │ │ │ └── TransactionConsumer.java │ │ └── resources/ │ │ └── application.properties │ ├── dubbo-provider/ │ │ ├── .gitignore │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── geekq/ │ │ │ └── dubbo/ │ │ │ └── springboot/ │ │ │ └── privoder/ │ │ │ ├── PrivoderApplication.java │ │ │ ├── config/ │ │ │ │ └── TCCConfig.java │ │ │ ├── quickstart/ │ │ │ │ └── QuickstartServiceImpl.java │ │ │ └── transaction/ │ │ │ ├── CapServiceImpl.java │ │ │ └── TransactionServiceImpl.java │ │ └── resources/ │ │ └── application.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── mooc/ │ │ └── jiangzh/ │ │ └── dubbo/ │ │ └── springboot/ │ │ └── springbootdubbo/ │ │ └── SpringbootDubboApplication.java │ └── resources/ │ └── application.properties ├── miaosha-v1/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── geekq/ │ │ └── miaosha/ │ │ ├── GeekQMainApplication.java │ │ ├── access/ │ │ │ ├── AccessInterceptor.java │ │ │ ├── AccessKey.java │ │ │ ├── AccessLimit.java │ │ │ └── UserContext.java │ │ ├── common/ │ │ │ ├── Constanst.java │ │ │ ├── SnowflakeIdWorker.java │ │ │ ├── enums/ │ │ │ │ ├── MessageStatus.java │ │ │ │ └── ResultStatus.java │ │ │ └── resultbean/ │ │ │ ├── AbstractResult.java │ │ │ └── ResultGeekQ.java │ │ ├── config/ │ │ │ ├── DruidConfig.java │ │ │ ├── UserArgumentResolver.java │ │ │ └── WebConfig.java │ │ ├── controller/ │ │ │ ├── BaseController.java │ │ │ ├── GoodsController.java │ │ │ ├── LoginController.java │ │ │ ├── MiaoShaMessageController.java │ │ │ ├── MiaoshaController.java │ │ │ ├── OrderController.java │ │ │ └── RegisterController.java │ │ ├── dao/ │ │ │ ├── GoodsDao.java │ │ │ ├── MiaoShaMessageDao.java │ │ │ ├── MiaoShaUserDao.java │ │ │ ├── OrderDao.java │ │ │ └── UserDao.java │ │ ├── domain/ │ │ │ ├── Goods.java │ │ │ ├── MiaoShaMessageInfo.java │ │ │ ├── MiaoShaMessageUser.java │ │ │ ├── MiaoshaGoods.java │ │ │ ├── MiaoshaOrder.java │ │ │ ├── MiaoshaUser.java │ │ │ ├── OrderInfo.java │ │ │ └── User.java │ │ ├── exception/ │ │ │ ├── GlobleException.java │ │ │ └── GlobleExceptionHandler.java │ │ ├── mybatis/ │ │ │ ├── Mapper/ │ │ │ │ └── UserMapper.java │ │ │ ├── README.md │ │ │ ├── controller/ │ │ │ │ └── UbatisController.java │ │ │ ├── entity/ │ │ │ │ └── User.java │ │ │ └── vo/ │ │ │ ├── TeacherListVo.java │ │ │ └── TeacherVo.java │ │ ├── rabbitmq/ │ │ │ ├── MQConfig.java │ │ │ ├── MQReceiver.java │ │ │ ├── MQSender.java │ │ │ └── MiaoshaMessage.java │ │ ├── redis/ │ │ │ ├── BasePrefix.java │ │ │ ├── DistributedLocker.java │ │ │ ├── GoodsKey.java │ │ │ ├── KeyPrefix.java │ │ │ ├── MiaoShaUserKey.java │ │ │ ├── MiaoshaKey.java │ │ │ ├── OrderKey.java │ │ │ ├── RedisConfig.java │ │ │ ├── RedisPoolFactory.java │ │ │ ├── RedisService.java │ │ │ ├── RedissLockUtil.java │ │ │ ├── RedissonAutoConfiguration.java │ │ │ ├── RedissonDistributedLocker.java │ │ │ ├── RedissonProperties.java │ │ │ ├── RedissonService.java │ │ │ ├── Userkey.java │ │ │ └── redismanager/ │ │ │ ├── OptimisticLockTest.java │ │ │ ├── RedisLock.java │ │ │ ├── RedisLua.java │ │ │ ├── RedisManager.java │ │ │ ├── RedisUtil.java │ │ │ └── lua/ │ │ │ ├── RedisLuaLock.java │ │ │ ├── luaLockScript.lua │ │ │ ├── test.lua │ │ │ └── testlua.lua │ │ ├── service/ │ │ │ ├── GoodsService.java │ │ │ ├── MiaoShaMessageService.java │ │ │ ├── MiaoShaUserService.java │ │ │ ├── MiaoshaService.java │ │ │ ├── OrderService.java │ │ │ ├── UserService.java │ │ │ └── rpchander/ │ │ │ ├── RpcCompensateService.java │ │ │ ├── RpcHandler.java │ │ │ ├── enums/ │ │ │ │ ├── PlanStepStatus.java │ │ │ │ └── PlanStepType.java │ │ │ └── vo/ │ │ │ ├── HandlerParam.java │ │ │ ├── PlanOrder.java │ │ │ └── PlanStep.java │ │ ├── timeTask/ │ │ │ └── OrderCloseTask.java │ │ ├── utils/ │ │ │ ├── DBUtil.java │ │ │ ├── DateTimeUtils.java │ │ │ ├── MD5Util.java │ │ │ ├── MD5Utils.java │ │ │ ├── UUIDUtil.java │ │ │ ├── UserUtil.java │ │ │ └── ValidatorUtil.java │ │ ├── validator/ │ │ │ ├── MobileCheck.java │ │ │ └── MobileValidator.java │ │ └── vo/ │ │ ├── GoodsDetailVo.java │ │ ├── GoodsVo.java │ │ ├── LoginVo.java │ │ ├── MiaoShaMessageVo.java │ │ └── OrderDetailVo.java │ └── resources/ │ ├── application-dev.properties │ ├── application-prod.properties │ ├── application-test.properties │ ├── application.properties │ ├── config/ │ │ └── application-test.properties │ ├── dubbo/ │ │ └── applicationContext-dubbo-consumer.xml │ ├── generatorConfig.xml │ ├── mybatis/ │ │ ├── conf.xml │ │ ├── mapper/ │ │ │ └── userMapper.xml │ │ └── mybatis-config.xml │ ├── static/ │ │ ├── bootstrap/ │ │ │ ├── css/ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ └── bootstrap.css │ │ │ └── js/ │ │ │ ├── bootstrap.js │ │ │ └── npm.js │ │ ├── css/ │ │ │ ├── common.css │ │ │ └── reset.css │ │ ├── fonts/ │ │ │ └── FontAwesome.otf │ │ ├── goods_detail.htm │ │ ├── js/ │ │ │ ├── common.js │ │ │ └── common1.js │ │ ├── layer/ │ │ │ ├── layer.js │ │ │ ├── mobile/ │ │ │ │ ├── layer.js │ │ │ │ └── need/ │ │ │ │ └── layer.css │ │ │ └── skin/ │ │ │ └── default/ │ │ │ └── layer.css │ │ └── order_detail.htm │ └── templates/ │ ├── goods_detail.html │ ├── goods_list.html │ ├── hello.html │ ├── index.html │ ├── login.html │ ├── message_list.html │ ├── miaosha_fail.html │ ├── order_detail.html │ ├── register.html │ └── register1.html ├── miaosha-v2/ │ ├── .gitignore │ ├── miaosha-common/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── com/ │ │ └── geekq/ │ │ └── miasha/ │ │ ├── entity/ │ │ │ ├── BaseDomain.java │ │ │ ├── Goods.java │ │ │ ├── IpLog.java │ │ │ ├── Logininfo.java │ │ │ ├── MiaoShaMessageInfo.java │ │ │ ├── MiaoShaMessageUser.java │ │ │ ├── MiaoshaGoods.java │ │ │ ├── MiaoshaOrder.java │ │ │ ├── MiaoshaUser.java │ │ │ └── OrderInfo.java │ │ ├── enums/ │ │ │ ├── Constanst.java │ │ │ ├── Constants.java │ │ │ ├── MessageStatus.java │ │ │ ├── OrderStatusEnum.java │ │ │ ├── SexEnum.java │ │ │ ├── YesOrNo.java │ │ │ ├── enums/ │ │ │ │ ├── MessageStatus.java │ │ │ │ └── ResultStatus.java │ │ │ └── resultbean/ │ │ │ ├── AbstractResult.java │ │ │ └── ResultGeekQ.java │ │ ├── exception/ │ │ │ └── GlobleException.java │ │ ├── utils/ │ │ │ ├── DateTimeUtils.java │ │ │ ├── MD5Utils.java │ │ │ ├── SnowflakeIdWorker.java │ │ │ ├── UUIDUtil.java │ │ │ ├── UserContext.java │ │ │ ├── UserContext2.java │ │ │ └── ValidatorUtil.java │ │ ├── validator/ │ │ │ ├── MobileCheck.java │ │ │ └── MobileValidator.java │ │ └── vo/ │ │ ├── GoodsDetailVo.java │ │ ├── GoodsVo.java │ │ ├── LoginVo.java │ │ ├── MiaoShaMessageVo.java │ │ └── OrderDetailVo.java │ ├── miaosha-service/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── geekq/ │ │ │ └── miaosha/ │ │ │ ├── mapper/ │ │ │ │ ├── GoodsMapper.java │ │ │ │ ├── GoodsMapper.xml │ │ │ │ ├── IpLogMapper.java │ │ │ │ ├── IpLogMapper.xml │ │ │ │ ├── LogininfoMapper.java │ │ │ │ ├── LogininfoMapper.xml │ │ │ │ ├── MiaoShaUserMapper.java │ │ │ │ ├── MiaoShaUserMapper.xml │ │ │ │ ├── OrderMapper.java │ │ │ │ └── OrderMapper.xml │ │ │ ├── rabbitmq/ │ │ │ │ ├── MQConfig.java │ │ │ │ ├── MQReceiver.java │ │ │ │ ├── MQSender.java │ │ │ │ └── MiaoshaMessage.java │ │ │ ├── redis/ │ │ │ │ ├── BasePrefix.java │ │ │ │ ├── DistributedLocker.java │ │ │ │ ├── GoodsKey.java │ │ │ │ ├── KeyPrefix.java │ │ │ │ ├── MiaoShaUserKey.java │ │ │ │ ├── MiaoshaKey.java │ │ │ │ ├── OrderKey.java │ │ │ │ ├── RedisConfig.java │ │ │ │ ├── RedisPoolFactory.java │ │ │ │ ├── RedisService.java │ │ │ │ ├── RedissLockUtil.java │ │ │ │ ├── Userkey.java │ │ │ │ └── redismanager/ │ │ │ │ ├── RedisLimitRateWithLUA.java │ │ │ │ ├── RedisLock.java │ │ │ │ ├── RedisLua.java │ │ │ │ ├── RedisManager.java │ │ │ │ └── lua/ │ │ │ │ ├── RedisLuaLock.java │ │ │ │ ├── limit.lua │ │ │ │ ├── luaLockScript.lua │ │ │ │ ├── test.lua │ │ │ │ └── testlua.lua │ │ │ └── service/ │ │ │ ├── GoodsService.java │ │ │ ├── LoginInfoService.java │ │ │ ├── MiaoShaMessageService.java │ │ │ ├── MiaoShaUserService.java │ │ │ ├── MiaoshaService.java │ │ │ ├── OrderService.java │ │ │ └── impl/ │ │ │ └── LoginInfoServiceImpl.java │ │ └── resources/ │ │ └── limit.lua │ ├── miaosha-web/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── geekq/ │ │ │ └── miaosha/ │ │ │ ├── GeekQMainApplication.java │ │ │ ├── config/ │ │ │ │ ├── DruidConfig.java │ │ │ │ ├── UserArgumentResolver.java │ │ │ │ └── WebConfig.java │ │ │ ├── controller/ │ │ │ │ ├── BaseController.java │ │ │ │ ├── GoodsController.java │ │ │ │ ├── LoginController.java │ │ │ │ ├── MiaoShaMessageController.java │ │ │ │ ├── MiaoshaController.java │ │ │ │ ├── OrderController.java │ │ │ │ └── RegisterController.java │ │ │ └── interceptor/ │ │ │ ├── AccessKey.java │ │ │ ├── GlobalExceptionHandler.java │ │ │ ├── GlobalParamAdvice.java │ │ │ ├── LoginInterceptor.java │ │ │ └── RequireLogin.java │ │ └── resources/ │ │ ├── application.properties │ │ ├── consumer.xml │ │ ├── css/ │ │ │ ├── account.css │ │ │ ├── bank.css │ │ │ ├── core.css │ │ │ └── slide-unlock.css │ │ ├── static/ │ │ │ ├── bootstrap/ │ │ │ │ ├── css/ │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ └── bootstrap.css │ │ │ │ └── js/ │ │ │ │ ├── bootstrap.js │ │ │ │ └── npm.js │ │ │ ├── css/ │ │ │ │ ├── common.css │ │ │ │ └── reset.css │ │ │ ├── fonts/ │ │ │ │ └── FontAwesome.otf │ │ │ ├── goods_detail.htm │ │ │ ├── js/ │ │ │ │ ├── My97DatePicker/ │ │ │ │ │ ├── My97DatePicker.htm │ │ │ │ │ ├── WdatePicker.js │ │ │ │ │ ├── calendar.js │ │ │ │ │ ├── config.js │ │ │ │ │ ├── lang/ │ │ │ │ │ │ ├── en.js │ │ │ │ │ │ ├── zh-cn.js │ │ │ │ │ │ └── zh-tw.js │ │ │ │ │ └── skin/ │ │ │ │ │ ├── WdatePicker.css │ │ │ │ │ ├── default/ │ │ │ │ │ │ └── datepicker.css │ │ │ │ │ └── whyGreen/ │ │ │ │ │ └── datepicker.css │ │ │ │ ├── bank.js │ │ │ │ ├── bootstrap-3.3.2-dist/ │ │ │ │ │ ├── css/ │ │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ │ └── bootstrap.css │ │ │ │ │ └── js/ │ │ │ │ │ ├── bootstrap.js │ │ │ │ │ └── npm.js │ │ │ │ ├── common.js │ │ │ │ ├── common1.js │ │ │ │ ├── jquery/ │ │ │ │ │ └── jquery-2.1.3.js │ │ │ │ ├── metisMenu/ │ │ │ │ │ ├── metisMenu.css │ │ │ │ │ └── metisMenu.js │ │ │ │ ├── plugins/ │ │ │ │ │ ├── datetimepicker/ │ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── .travis.yml │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ └── bootstrap-datetimepicker.css │ │ │ │ │ │ ├── js/ │ │ │ │ │ │ │ ├── bootstrap-datetimepicker.js │ │ │ │ │ │ │ └── locales/ │ │ │ │ │ │ │ └── bootstrap-datetimepicker.zh-CN.js │ │ │ │ │ │ ├── sample in bootstrap v2/ │ │ │ │ │ │ │ ├── bootstrap/ │ │ │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ │ │ └── bootstrap.css │ │ │ │ │ │ │ │ └── js/ │ │ │ │ │ │ │ │ └── bootstrap.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ └── sample in bootstrap v3/ │ │ │ │ │ │ ├── bootstrap/ │ │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ │ │ │ └── bootstrap.css │ │ │ │ │ │ │ └── js/ │ │ │ │ │ │ │ └── bootstrap.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── flipcountdown/ │ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── MIT-LICENSE.txt │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── bower.json │ │ │ │ │ │ ├── flipcountdown.jquery.json │ │ │ │ │ │ ├── img/ │ │ │ │ │ │ │ ├── am-pm-1.psd │ │ │ │ │ │ │ ├── digit-lg-dark.psd │ │ │ │ │ │ │ └── digit-lg.psd │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── jquery.flipcountdown.css │ │ │ │ │ │ ├── jquery.flipcountdown.js │ │ │ │ │ │ └── package.json │ │ │ │ │ ├── jquery-validation/ │ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── .travis.yml │ │ │ │ │ │ ├── demo/ │ │ │ │ │ │ │ ├── ajaxSubmit-intergration-demo.html │ │ │ │ │ │ │ ├── captcha/ │ │ │ │ │ │ │ │ ├── captcha.js │ │ │ │ │ │ │ │ ├── image_req.php │ │ │ │ │ │ │ │ ├── images/ │ │ │ │ │ │ │ │ │ ├── .htaccess │ │ │ │ │ │ │ │ │ └── image.php │ │ │ │ │ │ │ │ ├── index.php │ │ │ │ │ │ │ │ ├── newsession.php │ │ │ │ │ │ │ │ ├── process.php │ │ │ │ │ │ │ │ ├── rand.php │ │ │ │ │ │ │ │ └── style.css │ │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ │ ├── chili.css │ │ │ │ │ │ │ │ ├── cmxform.css │ │ │ │ │ │ │ │ ├── cmxformTemplate.css │ │ │ │ │ │ │ │ ├── core.css │ │ │ │ │ │ │ │ ├── reset.css │ │ │ │ │ │ │ │ └── screen.css │ │ │ │ │ │ │ ├── custom-messages-data-demo.html │ │ │ │ │ │ │ ├── custom-methods-demo.html │ │ │ │ │ │ │ ├── dynamic-totals.html │ │ │ │ │ │ │ ├── errorcontainer-demo.html │ │ │ │ │ │ │ ├── file_input.html │ │ │ │ │ │ │ ├── form.php │ │ │ │ │ │ │ ├── form.phps │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── jquerymobile.html │ │ │ │ │ │ │ ├── js/ │ │ │ │ │ │ │ │ └── chili-1.7.pack.js │ │ │ │ │ │ │ ├── login/ │ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ │ └── screen.css │ │ │ │ │ │ │ ├── marketo/ │ │ │ │ │ │ │ │ ├── emails.php │ │ │ │ │ │ │ │ ├── emails.phps │ │ │ │ │ │ │ │ ├── ie6.css │ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ │ ├── jquery.maskedinput.js │ │ │ │ │ │ │ │ ├── mktSignup.js │ │ │ │ │ │ │ │ ├── step2.htm │ │ │ │ │ │ │ │ └── stylesheet.css │ │ │ │ │ │ │ ├── milk/ │ │ │ │ │ │ │ │ ├── emails.php │ │ │ │ │ │ │ │ ├── emails.phps │ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ │ ├── milk.css │ │ │ │ │ │ │ │ ├── users.php │ │ │ │ │ │ │ │ └── users.phps │ │ │ │ │ │ │ ├── multipart/ │ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ │ ├── js/ │ │ │ │ │ │ │ │ │ ├── jquery.maskedinput-1.0.js │ │ │ │ │ │ │ │ │ ├── ui.accordion.js │ │ │ │ │ │ │ │ │ └── ui.core.js │ │ │ │ │ │ │ │ └── style.css │ │ │ │ │ │ │ ├── radio-checkbox-select-demo.html │ │ │ │ │ │ │ ├── tabs/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── themerollered.html │ │ │ │ │ │ │ └── tinymce/ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── themes/ │ │ │ │ │ │ │ │ └── simple/ │ │ │ │ │ │ │ │ ├── editor_template.js │ │ │ │ │ │ │ │ ├── langs/ │ │ │ │ │ │ │ │ │ └── en.js │ │ │ │ │ │ │ │ └── skins/ │ │ │ │ │ │ │ │ └── default/ │ │ │ │ │ │ │ │ └── ui.css │ │ │ │ │ │ │ └── tiny_mce.js │ │ │ │ │ │ ├── jquery.validate.js │ │ │ │ │ │ ├── lib/ │ │ │ │ │ │ │ ├── jquery-1.6.4.js │ │ │ │ │ │ │ ├── jquery-1.7.2.js │ │ │ │ │ │ │ ├── jquery-1.8.3.js │ │ │ │ │ │ │ ├── jquery-1.9.0.js │ │ │ │ │ │ │ ├── jquery.form.js │ │ │ │ │ │ │ ├── jquery.js │ │ │ │ │ │ │ └── jquery.mockjax.js │ │ │ │ │ │ └── localization/ │ │ │ │ │ │ └── messages_zh.js │ │ │ │ │ ├── jquery.form.js │ │ │ │ │ ├── jquery.twbsPagination.js │ │ │ │ │ └── uploadify/ │ │ │ │ │ ├── jquery.uploadify.js │ │ │ │ │ └── uploadify.swf │ │ │ │ └── plugins-override.js │ │ │ ├── layer/ │ │ │ │ ├── layer.js │ │ │ │ ├── mobile/ │ │ │ │ │ ├── layer.js │ │ │ │ │ └── need/ │ │ │ │ │ └── layer.css │ │ │ │ └── skin/ │ │ │ │ └── default/ │ │ │ │ └── layer.css │ │ │ └── order_detail.htm │ │ └── templates/ │ │ ├── bootstrap/ │ │ │ ├── css/ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ └── bootstrap.css │ │ │ └── js/ │ │ │ ├── bootstrap.js │ │ │ └── npm.js │ │ ├── css/ │ │ │ ├── common.css │ │ │ ├── common1.css │ │ │ ├── reset.css │ │ │ └── slide-unlock.css │ │ ├── fonts/ │ │ │ └── FontAwesome.otf │ │ ├── goods_list.html │ │ ├── hello.html │ │ ├── index.html │ │ ├── index2.html │ │ ├── js/ │ │ │ ├── My97DatePicker/ │ │ │ │ ├── My97DatePicker.htm │ │ │ │ ├── WdatePicker.js │ │ │ │ ├── calendar.js │ │ │ │ ├── config.js │ │ │ │ ├── lang/ │ │ │ │ │ ├── en.js │ │ │ │ │ ├── zh-cn.js │ │ │ │ │ └── zh-tw.js │ │ │ │ └── skin/ │ │ │ │ ├── WdatePicker.css │ │ │ │ ├── default/ │ │ │ │ │ └── datepicker.css │ │ │ │ └── whyGreen/ │ │ │ │ └── datepicker.css │ │ │ ├── bank.js │ │ │ ├── bootstrap-3.3.2-dist/ │ │ │ │ ├── css/ │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ └── bootstrap.css │ │ │ │ └── js/ │ │ │ │ ├── bootstrap.js │ │ │ │ └── npm.js │ │ │ ├── common.js │ │ │ ├── common1.js │ │ │ ├── jquery/ │ │ │ │ └── jquery-2.1.3.js │ │ │ ├── metisMenu/ │ │ │ │ ├── metisMenu.css │ │ │ │ └── metisMenu.js │ │ │ ├── plugins/ │ │ │ │ ├── datetimepicker/ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .travis.yml │ │ │ │ │ ├── README.md │ │ │ │ │ ├── css/ │ │ │ │ │ │ └── bootstrap-datetimepicker.css │ │ │ │ │ ├── js/ │ │ │ │ │ │ ├── bootstrap-datetimepicker.js │ │ │ │ │ │ └── locales/ │ │ │ │ │ │ └── bootstrap-datetimepicker.zh-CN.js │ │ │ │ │ ├── sample in bootstrap v2/ │ │ │ │ │ │ ├── bootstrap/ │ │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ │ └── bootstrap.css │ │ │ │ │ │ │ └── js/ │ │ │ │ │ │ │ └── bootstrap.js │ │ │ │ │ │ └── index.html │ │ │ │ │ └── sample in bootstrap v3/ │ │ │ │ │ ├── bootstrap/ │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ │ │ └── bootstrap.css │ │ │ │ │ │ └── js/ │ │ │ │ │ │ └── bootstrap.js │ │ │ │ │ └── index.html │ │ │ │ ├── flipcountdown/ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── MIT-LICENSE.txt │ │ │ │ │ ├── README.md │ │ │ │ │ ├── bower.json │ │ │ │ │ ├── flipcountdown.jquery.json │ │ │ │ │ ├── img/ │ │ │ │ │ │ ├── am-pm-1.psd │ │ │ │ │ │ ├── digit-lg-dark.psd │ │ │ │ │ │ └── digit-lg.psd │ │ │ │ │ ├── index.html │ │ │ │ │ ├── jquery.flipcountdown.css │ │ │ │ │ ├── jquery.flipcountdown.js │ │ │ │ │ └── package.json │ │ │ │ ├── jquery-validation/ │ │ │ │ │ ├── .gitattributes │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .travis.yml │ │ │ │ │ ├── demo/ │ │ │ │ │ │ ├── ajaxSubmit-intergration-demo.html │ │ │ │ │ │ ├── captcha/ │ │ │ │ │ │ │ ├── captcha.js │ │ │ │ │ │ │ ├── image_req.php │ │ │ │ │ │ │ ├── images/ │ │ │ │ │ │ │ │ ├── .htaccess │ │ │ │ │ │ │ │ └── image.php │ │ │ │ │ │ │ ├── index.php │ │ │ │ │ │ │ ├── newsession.php │ │ │ │ │ │ │ ├── process.php │ │ │ │ │ │ │ ├── rand.php │ │ │ │ │ │ │ └── style.css │ │ │ │ │ │ ├── css/ │ │ │ │ │ │ │ ├── chili.css │ │ │ │ │ │ │ ├── cmxform.css │ │ │ │ │ │ │ ├── cmxformTemplate.css │ │ │ │ │ │ │ ├── core.css │ │ │ │ │ │ │ ├── reset.css │ │ │ │ │ │ │ └── screen.css │ │ │ │ │ │ ├── custom-messages-data-demo.html │ │ │ │ │ │ ├── custom-methods-demo.html │ │ │ │ │ │ ├── dynamic-totals.html │ │ │ │ │ │ ├── errorcontainer-demo.html │ │ │ │ │ │ ├── file_input.html │ │ │ │ │ │ ├── form.php │ │ │ │ │ │ ├── form.phps │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── jquerymobile.html │ │ │ │ │ │ ├── js/ │ │ │ │ │ │ │ └── chili-1.7.pack.js │ │ │ │ │ │ ├── login/ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── screen.css │ │ │ │ │ │ ├── marketo/ │ │ │ │ │ │ │ ├── emails.php │ │ │ │ │ │ │ ├── emails.phps │ │ │ │ │ │ │ ├── ie6.css │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── jquery.maskedinput.js │ │ │ │ │ │ │ ├── mktSignup.js │ │ │ │ │ │ │ ├── step2.htm │ │ │ │ │ │ │ └── stylesheet.css │ │ │ │ │ │ ├── milk/ │ │ │ │ │ │ │ ├── emails.php │ │ │ │ │ │ │ ├── emails.phps │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── milk.css │ │ │ │ │ │ │ ├── users.php │ │ │ │ │ │ │ └── users.phps │ │ │ │ │ │ ├── multipart/ │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── js/ │ │ │ │ │ │ │ │ ├── jquery.maskedinput-1.0.js │ │ │ │ │ │ │ │ ├── ui.accordion.js │ │ │ │ │ │ │ │ └── ui.core.js │ │ │ │ │ │ │ └── style.css │ │ │ │ │ │ ├── radio-checkbox-select-demo.html │ │ │ │ │ │ ├── tabs/ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── themerollered.html │ │ │ │ │ │ └── tinymce/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── themes/ │ │ │ │ │ │ │ └── simple/ │ │ │ │ │ │ │ ├── editor_template.js │ │ │ │ │ │ │ ├── langs/ │ │ │ │ │ │ │ │ └── en.js │ │ │ │ │ │ │ └── skins/ │ │ │ │ │ │ │ └── default/ │ │ │ │ │ │ │ └── ui.css │ │ │ │ │ │ └── tiny_mce.js │ │ │ │ │ ├── jquery.validate.js │ │ │ │ │ ├── lib/ │ │ │ │ │ │ ├── jquery-1.6.4.js │ │ │ │ │ │ ├── jquery-1.7.2.js │ │ │ │ │ │ ├── jquery-1.8.3.js │ │ │ │ │ │ ├── jquery-1.9.0.js │ │ │ │ │ │ ├── jquery.form.js │ │ │ │ │ │ ├── jquery.js │ │ │ │ │ │ └── jquery.mockjax.js │ │ │ │ │ └── localization/ │ │ │ │ │ └── messages_zh.js │ │ │ │ ├── jquery.form.js │ │ │ │ ├── jquery.twbsPagination.js │ │ │ │ └── uploadify/ │ │ │ │ ├── jquery.uploadify.js │ │ │ │ └── uploadify.swf │ │ │ ├── plugins-override.js │ │ │ └── slideunlock/ │ │ │ └── slideunlock.js │ │ ├── layer/ │ │ │ ├── layer.js │ │ │ ├── mobile/ │ │ │ │ ├── layer.js │ │ │ │ └── need/ │ │ │ │ └── layer.css │ │ │ └── skin/ │ │ │ └── default/ │ │ │ └── layer.css │ │ ├── login.html │ │ ├── login222.html │ │ ├── message_list.html │ │ ├── miaosha_fail.html │ │ ├── order_detail.html │ │ ├── register.html │ │ ├── register1.html │ │ ├── register2.html │ │ └── test.html │ ├── miaosha.sql │ └── pom.xml ├── old.md ├── pom.xml └── sql/ ├── miaosha.sql └── miaosha1.sql ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ *.js linguist-language=java *.css linguist-language=java *.html linguist-language=java ================================================ FILE: .gitignore ================================================ # IntelliJ project files .DS_Store .idea/ *.iml .mvn/* out # CMake cmake-build-*/ # File-based project format *.iws # IntelliJ out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties ### Java template # Compiled class file *.class # Log file *.log # BlueJ files *.ctxt # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.war *.nar *.ear *.zip *.tar.gz *.rar .settings/ .mvn/ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* ### Maven template target/ pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup pom.xml.next release.properties dependency-reduced-pom.xml buildNumber.properties ================================================ FILE: CHANGELOG.md ================================================ ## 修改记录 ### 1.0.0 - 将秒杀项目进行模块化划分 - 基础依赖版本升级 - 新增.mvn等无需跟踪文件 ================================================ FILE: README.md ================================================ 大家好,我是GEEK.Q,我对自己的经验知识做了一个系统的整理,有自己的迭代项目,框架,也有一些学习笔记和画的图。 本GitHub还有许多其他的知识,随时欢迎探讨与骚扰!如果想一起**维护**或者**文章出现瑕疵**请及时与我联系【邮箱QiuRunZe_key@163.com】! 一点小建议:学习本系列知识之前,如果你完全没接触过 `[深入]Spring[不深入框架可能理解起来比较费劲]`、`MQ`、`SpringBoot`、`Redis`、`Dubbo`、`ZK` 、`Maven`,`lua`等,那么我建议你可以先在网上搜一下每一块知识的快速入门。tydeus-monito框架这个项目可以说是非常好的解决**日志**痛点 ### tydeus-monito框架 > tydeus-monitor : [https://github.com/qiurunze123/tydeus-monitor](https://github.com/qiurunze123/tydeus-monitor) 一种为监控而生的日志解决方案 "监控"多种多样,网上一搜,花样百出,每个公司都会有自己的监控系统,大部分的功能都为监视+报警系统,很少有业务控制和系统控制的相关功能 本文主要讲解为业务系统指标相关监控、如何更快捷方便优雅地打出你需要的日志、而不需要镶嵌在各个业务环节中 * 进线率 * 完结率 * 成功失败率 * 各种姿势打印各种类型日志【入参、出参、异常】 ### 多线程学习与讲解+三高导入框架 > 多线程学习与讲解 : [https://github.com/qiurunze123/threadandjuc](https://github.com/qiurunze123/threadandjuc) three-high-import 项目意义在于利用多线程进行千万级别导入,实现可扩展,高性能,高可用,高可靠三个高,本项目可以在千万级别数据实现无差别高性能数据上报 与导入,与普通导入相比性能提高10倍左右,而且规避风险在偶尔的机器宕机,网络波动等情况出现时,仍能够实现数据一致,数据可靠,数据重试,数据报警等功能,在一些重要数据 例如: 对账 , 账户金额,账单等,需要每日定时任务而且有高风险的数据实现数据无错误! 多线程从基础到进阶,分析入坑出坑,以及工作实操,最后会分享一个项目,针对如何进行大数据量(经测试几亿数据完全搞的定)进行安全高可用的策略, 示例为高可用高可靠高性能 三高导入系统 DEMO分析 ,如何进行数据分片,数据导入,计算,多线程策略等等 本文属于进阶系列,有问题或者更好的想法可以一起探讨! ### JVM内存学习与讲解 > JVM内存学习与讲解 : [https://github.com/qiurunze123/memoryoptimization/blob/master/README.md](https://github.com/qiurunze123/memoryoptimization/blob/master/README.md) 本项目介绍 : JVM内存调优与生产实战 简单说明下 在项目上线之初,我们应该如何设置JVM的参数配置,我们如何分配内存空间会使效率最大化,当项目上线后我们如何监控项目的内存情况呢? 我们又如何来查看内存的溢出情况,分析GC日志呢?...... 这个项目就是为了这些研究这些可能大家平时不会考虑的东西来应运而生? 此项目仍为进阶课程,一些简单的请提前预习! ### 节点轻量级流程引擎 > 编排节点轻量级流程引擎 : [https://github.com/qiurunze123/qrzFlowEngine](https://github.com/qiurunze123/qrzFlowEngine) 之前业内有证明了随着架构设计时间的增加,开发和返工量都会减少,所以在这有限时间内,找到一个最佳平衡点来进行设计是一个问题,那么如何来找到最佳平衡点,让我们少走弯路,既能够灵活设计,又能够按时上线,又能够符合当下现状和需求成本了本次文章探讨的命题,本文将从复杂机审流程进行举例,来看下踩了哪些坑,又做对了哪些事情,最后终于在架构【需求+设计+时间】 = 设计平衡点!也就是本次框架设计的初衷! ### zookeeper设计哲学 > zookeeper设计哲学 : [https://github.com/qiurunze123/zookeeperDesign](https://github.com/qiurunze123/zookeeperDesign) 此项目是为了适应互联网分布式架构的背景下的集群管理,多个节点的互相协调的问题等! ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件 ,它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等 此项目可以带大家深入了解zk在分布式项目中发挥了什么作用! ### 设计模式哲学 > 设计模式哲学 : [https://github.com/qiurunze123/Designpattern](https://github.com/qiurunze123/Designpattern) 此项目是为了适应互联网分布式架构的背景下的集群管理,多个节点的互相协调的问题等! ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件 ,它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等 此项目可以带大家深入了解zk在分布式项目中发挥了什么作用! ### 原版+轻量级秒杀 停更 > 原老版ms : [https://github.com/qiurunze123/miaosha/blob/master/old.md](https://github.com/qiurunze123/miaosha/blob/master/old.md) 已不更新、如果想看之前思考记录文档和一些画的图可以看下 > demo-airtravel版ms : [https://github.com/qiurunze123/aircrafttravel/blob/master/README.md](https://github.com/qiurunze123/aircrafttravel/blob/master/README.md) 已不更新、如果想看之前思考记录文档和一些画的图可以看下 ================================================ FILE: docs/code-criterion.md ================================================ ### 代码规范 老司机一般的规范大家都知道类似驼峰,匹配一类的大家都知道具体则不再提 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ##要求: 1.lombok-- idea插件请大家下载 ,去除setget构造方法等,阿里巴巴代码规范插件请自行下载
2.**尽量将长的类名,方法名,变量名精简**
1.长的类名会使开发者不易生命该类型的变量 2.长的方法命名会使它变得晦涩难懂 3.长的变量名不利于代码重用,导致过长的方法链 3.**命名清晰准确**
清晰: 你要知道该命名于什么有关 精确:你要知道该命名于什么无关 当完成这两个目标后其他的都是多余的字符 4.**命名无需含有表示变量或者参数类型的单词**
nameString 请写成 name accountLessWindow 请写成 window 5.**对于集合来说,最好使用名词的复数形式来描述内容**
List holidayDateLists 请写成 List holidays Map employeeRoleHashMap 请写成 Map employeeRoles 6.**方法名不需要描述它的参数及参数的类型–参数列表已经说明了这些**
mergeTableCells(List cells) 请写成 merge(List cells) sortEventsUsingComparator(List events,Comparator comparator) 请写成 sort(List events, Comparator comparator) 7.**省略命名中不是用来消除歧义的单词**
8.**命名只是一个表示符,只要告诉你变量在哪定义不需要吧所有的信息都塞到命名里面**
recentlyUpdatedAnnualSalesBid 存在不是最近更新的全年销售投标么? 存在没有被更新的最近的全年销售投标么? 存在最近更新的非全年的销售投标么? 存在最近更新的全年非销售的投标么? 存在最近更新的全年销售非投标的东东吗? 上面的任何一个问题回答是不存在,那就意味着命名中引入了无用的单词 finalBattleMostDangerousBossMonster 请写成 boss weaklingFirstEncounterMonster 请写成firstMonster 如果有一些你觉得过了,太短了,容易引起歧义,但是你可以大胆的这样做,如果在之后的开发中你觉得命名会造成冲突和不明确 你可以填一些修饰词来完善它,反之如果一开始就是一个很长的名字,你不可能再改回来 9.**省略命名中可以从上下文获取的单词**
// Bad: class AnnualHolidaySale { int _annualSaleRebate; void promoteHolidaySale() { ... } } // Better: class AnnualHolidaySale { int _rebate; void promote() { ... } } 实际上一个命名嵌套的层次越多,他就有更多的相关的上下文,也就更简短,换句话说一个变量的作用域越小,命名就越短 10.**省略命名中无任何意义的单词**
例如:data、state、amount、value、manager、engine、object、entity 和 instance一类的 不需要这类严肃的词语 11.**是否可以描述出一幅画(我在装逼)**
一个好的命名能够在阅读者的脑海里面描绘出一幅图画,而降变量命名为manager 并不能象读者传达出任何有关该变量做什么的信息 在命名时可以问一下自己,把这个单词去掉含义是不是不变?如果是,那就果断把它剔除吧 12.**终极一例**
例子:好吃的华夫饼 // 好吃的比利时华夫饼 class DeliciousBelgianWaffleObject { void garnishDeliciousBelgianWaffleWithStrawberryList( List strawberryList) { ... } } 首先,通过参数列表,我们可以知道方法是用来处理一个strawberry 的列表 所以可以在方法的命名中去掉 class DeliciousBelgianWaffleObject { void garnishDeliciousBelgianWaffle( List strawberries) { ... } } 除非程序中还包含不好吃的比利时华夫饼或者其它华夫饼 不然我们可以将这个无用的形容词去掉 class WaffleObject { void garnishWaffle(List strawberries) { ... } } 方法是包含在waffleObject类中的 所以方法名无需waffle说明 class WaffleObject { void garnish(List strawberries) { ... } } 很明显他是一个对象,任何事物都是一个对象,这也就是传说中的面相对象的意思,所以命名中无需带有Object class Waffle { void garnish(List strawberries) { ... } } 13.**类名应该是名词不应该是动词,使用普遍的被大众理解的词**
14.**请勿抛异常直接返回**
类似如下规范 Result result=Result.build(); boolean isChecking = redisServiceUtil.getIsCheckingOfAutomatedLoanService(); result.setValue(isChecking); if (isChecking) { logger.info("--- isSystemChecking ---系统清算中-----"); result.withError(ResultMsgStatus.SYSTEM_CHECKING.getMessage()); } return result; ================================================ FILE: docs/code-rpc.md ================================================ ### 分布式事务的讲解与实现 基础的ACID等等就不一一介绍了 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ##简介: 基础的ACID等等就不一一介绍了,柔性事务一类的大家在网上一搜都是,可以先看看基础的! 我的github都是实际操作加讲解,我觉得写文章大篇大论浪费时间,不如实际操作来的深刻 感谢大家支持! 1.tcc事务演进与场景 2.tcc事务源码解析与实际操作 3.分布式事务的实操与演进 2. **TCC事务的简介** 两段式事务 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/liangduanshi.JPG) 三段式事务 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/tcc.JPG) TCC的优点: 1.解决了扩应用的业务操作的原子性问题 2.数据库的二阶段提交提到了应用层实现 使用场景: 组合支付,账务一类的 比较要求强一致性高的场景使用 Tcc项目地址: [![地址](tcc地址)](https://github.com/changmingxie/tcc-transaction/tree/master-1.2.x) 如果你想 用dubbo的他的还不行有点错误请下载: (使用请先参考TCC文档) [![地址](tcc-dubbo地址)](https://github.com/qiurunze123/tcc-dubbo) 效果图: ![效果图](https://raw.githubusercontent.com/qiurunze123/imageall/master/tcc.gif) |_tcc-transaction-dubbo| |_1 字节码代理 -> 创建接口的代理对象 |_2 DubboTransactionContextEditor -> TRANSACTION_CONTEXT[标识事务状态]利用Dubbo的隐式参数来传递关键的非业务数据 |_tcc-transaction-spring| |_封装了一些关键的Spring组件 |_questions| |_1、什么时候生成的TRANSACTION_CONTEXT隐式参数 |_2、如何判断一个大的事务下,都有哪些小的事务 |_3、为什么要有@Compensable注解 |_4、两个拦截器都没有处理Confirm和Cancel |_基础概念 | |_主事务和分支事务【事务参与者】 |_事务拦截器作用:[Spring AOP的基本概念要熟练掌握]|_1 CompensableTransactionInterceptor |_ 将事务区分为Root事务和分支事务 |_不断的修改数据库内的状态【初始化事务,修改事务状态】 |_注册和清除事务管理器中队列内容 |_ResourceCoordinatorInterceptor |_主要处理try阶段的事情 |_在try阶段,就将所有的"资源"封装完成并交给事务管理器 |_资源 -- 事务资源 事务的参与者 |_1.Confirm上下文 |_2.Cancel上下文 |_3.分支事务信息 |_4.事务管理器修改数据库状态 |_ 调用目标对象 -- order red cap |_小结 |_ 1.事务的相关信息【全局事务编号,乐观锁版本等要持久化存储】 |_ 2.资源:* TCC 【try-confirm-cancel】 try核心点: 预留业务资源 把事务数据资源存入库中 |_ 3 流程: |_注册和初始化事务 |_组织事务参与者 |_执行目标try方法 |_执行confirm和cancel方法 ================================================ FILE: docs/code-solve.md ================================================ ### 秒杀常见问题 有问题或者宝贵意见联系我的QQ,非常希望你的加入! > 秒杀注意事项以及整体简略设计 #### [1.如何解决卖超问题]() --在sql加上判断防止数据变为负数 --数据库加唯一索引防止用户重复购买 --redis预减库存减少数据库访问 内存标记减少redis访问 请求先入队列缓冲,异步下单,增强用户体验 #### [注册功能 -- 如果有前端的牛人加入修改几个页面那是再好不过了哈哈哈]() #### [全局异常处理拦截]() 1.定义全局的异常拦截器 2.定义了全局异常类型 3.只返回和业务有关的 4.详情请看GlobleException #### [页面级缓存thymeleafViewResolver]() 1.详细请看basecontroller 缓存渲染页面 #### [对象级缓存redis🙋🐓]() redis永久缓存对象减少压力 redis预减库存减少数据库访 内存标记方法减少redis访问 #### [订单处理队列rabbitmq]() 请求先入队缓冲,异步下单,增强用户体验 请求出队,生成订单,减少库存 客户端定时轮询检查是否秒杀成功 #### [解决分布式session]() --生成随机的uuid作为cookie返回并redis内存写入 --拦截器每次拦截方法,来重新获根据cookie获取对象 --下一个页面拿到key重新获取对象 --HandlerMethodArgumentResolver 方法 supportsParameter 如果为true 执行 resolveArgument 方法获取miaoshauser对象 --如果有缓存的话 这个功能实现起来就和简单,在一个用户访问接口的时候我们把访问次数写到缓存中,在加上一个有效期。 通过拦截器. 做一个注解 @AccessLimit 然后封装这个注解,可以有效的设置每次访问多少次,有效时间是否需要登录! #### [秒杀安全 -- 安全性设计]() 秒杀接口隐藏 数字公式验证码 接口防刷限流(通用 注解,拦截器方式) #### [通用缓存key的封装采用什么设计模式]() 模板模式的优点 -具体细节步骤实现定义在子类中,子类定义详细处理算法是不会改变算法整体结构 -代码复用的基本技术,在数据库设计中尤为重要 -存在一种反向的控制结构,通过一个父类调用其子类的操作,通过子类对父类进行扩展增加新的行为,符合“开闭原则” -缺点: 每个不同的实现都需要定义一个子类,会导致类的个数增加,系统更加庞大 #### [redis的库存如何与数据库的库存保持一致]() redis的数量不是库存,他的作用仅仅只是为了阻挡多余的请求透穿到DB,起到一个保护的作用 因为秒杀的商品有限,比如10个,让1万个请求区访问DB是没有意义的,因为最多也就只能10个 请求下单成功,所有这个是一个伪命题,我们是不需要保持一致的 #### [redis 预减成功,DB扣减库存失败怎么办]() -其实我们可以不用太在意,对用户而言,秒杀不中是正常现象,秒杀中才是意外,单个用户秒杀中 -1.本来就是小概率事件,出现这种情况对于用户而言没有任何影响 -2.对于商户而言,本来就是为了活动拉流量人气的,卖不完还可以省一部分费用,但是活动还参与了,也就没有了任何影响 -3.对网站而言,最重要的是体验,只要网站不崩溃,对用户而言没有任何影响 #### [为什么redis数量会减少为负数]() //预见库存 long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock,""+goodsId) ; if(stock <0){ localOverMap.put(goodsId, true); return Result.error(CodeMsg.MIAO_SHA_OVER); } 假如redis的数量为1,这个时候同时过来100个请求,大家一起执行decr数量就会减少成-99这个是正常的 进行优化后改变了sql写法和内存写法则不会出现上述问题 #### [为什么要单独维护一个秒杀结束标志]() -1.前提所有的秒杀相关的接口都要加上活动是否结束的标志,如果结束就直接返回,包括轮寻的接口防止一直轮寻 -2.管理后台也可以手动的更改这个标志,防止出现活动开始以后就没办法结束这种意外的事件 #### [rabbitmq如何做到消息不重复不丢失即使服务器重启]() -1.exchange持久化 -2.queue持久化 -3.发送消息设置MessageDeliveryMode.persisent这个也是默认的行为 -4.手动确认 #### [为什么threadlocal存储user对象,原理]() 1.并发编程中重要的问题就是数据共享,当你在一个线程中改变任意属性时,所有的线程都会因此受到影响,同时会看到第一个线程修改后的值
有时我们希望如此,比如:多个线程增大或减小同一个计数器变量
但是,有时我们希望确保每个线程,只能工作在它自己 的线程实例的拷贝上,同时不会影响其他线程的数据
举例: 举个例子,想象你在开发一个电子商务应用,你需要为每一个控制器处理的顾客请求,生成一个唯一的事务ID,同时将其传到管理器或DAO的业务方法中, 以便记录日志。一种方案是将事务ID作为一个参数,传到所有的业务方法中。但这并不是一个好的方案,它会使代码变得冗余。 你可以使用ThreadLocal类型的变量解决这个问题。首先在控制器或者任意一个预处理器拦截器中生成一个事务ID 然后在ThreadLocal中 设置事务ID,最后,不论这个控制器调用什么方法,都能从threadlocal中获取事务ID 而且这个应用的控制器可以同时处理多个请求, 同时在框架 层面,因为每一个请求都是在一个单独的线程中处理的,所以事务ID对于每一个线程都是唯一的,而且可以从所有线程的执行路径获取 运行结果可以看出每个线程都在维护自己的变量: Starting Thread: 0 : Fri Sep 21 23:05:34 CST 2018
Starting Thread: 2 : Fri Sep 21 23:05:34 CST 2018
Starting Thread: 1 : Fri Jan 02 05:36:17 CST 1970
Thread Finished: 1 : Fri Jan 02 05:36:17 CST 1970
Thread Finished: 0 : Fri Sep 21 23:05:34 CST 2018
Thread Finished: 2 : Fri Sep 21 23:05:34 CST 2018
局部线程通常使用在这样的情况下,当你有一些对象并不满足线程安全,但是你想避免在使用synchronized关键字
块时产生的同步访问,那么,让每个线程拥有它自己的对象实例
注意:局部变量是同步或局部线程的一个好的替代,它总是能够保证线程安全。唯一可能限制你这样做的是你的应用设计约束
所以设计threadlocal存储user不会对对象产生影响,每次进来一个请求都会产生自身的线程变量来存储 #### [maven 隔离]() maven隔离就是在开发中,把各个环境的隔离开来,一般分为 本地(local) 开发(dev) 测试(test) 线上(prod) 在环境部署中为了防止人工修改的弊端! spring.profiles.active=@activatedProperties@ #### [redis 分布式锁实现方法]() 我用了四种方法 , 分别指出了不同版本的缺陷以及演进的过程 orderclosetask V1---->>版本没有操作,在分布式系统中会造成同一时间,资源浪费而且很容易出现并发问题 V2--->>版本加了分布式redis锁,在访问核心方法前,加入redis锁可以阻塞其他线程访问,可以 很好的处理并发问题,但是缺陷就是如果机器突然宕机,或者线路波动等,就会造成死锁,一直 不释放等问题 V3版本-->>很好的解决了这个问题v2的问题,就是加入时间对比如果当前时间已经大与释放锁的时间 说明已经可以释放这个锁重新在获取锁,setget方法可以把之前的锁去掉在重新获取,旧值在于之前的 值比较,如果无变化说明这个期间没有人获取或者操作这个redis锁,则可以重新获取 V4---->>采用成熟的框架redisson,封装好的方法则可以直接处理,但是waittime记住要这只为0 #### [服务降级--服务熔断(过载保护))]() 自动降级: 超时.失败次数,故障,限流 人工降级:秒杀,双11 9.所有秒杀相关的接口比如:秒杀,获取秒杀地址,获取秒杀结果,获取秒杀验证码都需要加上 秒杀是否开始结束的判断 #### [RPC事务补偿]() 当集中式进行服务化RPC演进成分布式的时候,事务则成为了进行分布式的一个痛点,本项目的做法为: 1.进行流程初始化,当分别调用不用服务化接口的时候,成功则进行流程,失败则返回并进行状态更新 将订单状态变为回滚 2.使用定时任务不断的进行处理rollback的订单进行回滚 #### [秒杀类似场景sql的写法注意事项]() 1.在秒杀一类的场景里面,因为数据量亿万级所有即使有的有缓存有的时候也是扛不住的,不可避免的透穿到DB 所有在写一些sql的时候就要注意: 1.一定要避免全表扫描,如果扫一张大表的数据就会造成慢查询,导致数据的连接池直接塞满,导致事故 首先考虑在where和order by 设计的列上建立索引 例如: 1. where 子句中对字段进行 null 值判断 . 2. 应尽量避免在 where 子句中使用!=或<>操作符 3. 应尽量避免在 where 子句中使用 or 来连接条件 4. in 和 not in 也要慎用,否则会导致全表扫描( 如果索引 会优先走索引 不会导致全表扫描 字段上建了索引后,使用in不会全表扫描,而用not in 会全表扫描 低版本的mysql是两种情况都会全表扫描。 5.5版本后以修。而且在优化大表连接查询的时候,有一个方法就是将join操作拆分为in查询) 5. select id from t where name like '%abc%' 或者 6.select id from t where name like '%abc' 或者 7. 若要提高效率,可以考虑全文检索。 8.而select id from t where name like 'abc%' 才用到索引 慢查询一般在测试环境不容易复现 9.应尽量避免在 where 子句中对字段进行表达式操作 where num/2 num=100*2 2.合理的使用索引 索引并不是越多越好,使用不当会造成性能开销 3.尽量避免大事务操作,提高系统并发能力 4.尽量避免象客户端返回大量数据,如果返回则要考虑是否需求合理,实在不得已则需要在设计一波了!!!!! #### [网站访问统计实现]() ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/count.png) 利用lua脚本进行对redis操作,登陆时,每次登陆成功则记录访问(具体你想在什么时段进行统计自己说了算) #### [项目进行dubbo+ZK改造]() ├── miaosha-admin 登录模块 │ ├── pom.xml │ └── miaosha-admin-api │ └── miaosha-admin-service │ └── miaosha-admin-web │ └── miaosha-common │ │ ├── miaosha-order 订单秒杀模块 │ ├── pom.xml │ └── miaosha-order-api │ └── miaosha-order-service │ └── miaosha-order-web │ └── miaosha-order-common │ │ ├── miaosha-message 消息模块 │ ├── pom.xml │ └── miaosha-message-api │ └── miaosha-message-service │ └── miaosha-message-web │ └── miaosha-message-common │ │ ================================================ FILE: docs/dubbo-admin.md ================================================ ### dubbo-admin 平台搭建与管理 有问题或者宝贵意见联系我的QQ,非常希望你的加入! #### [dubbo-admin-2.6.0 war包 请进入/docs/dubbo-admin/下载](/docs/dubbo-admin/dubbo-admin-2.6.0.war) 1.可直接 https://github.com/apache/incubator-dubbo/releases/tag/dubbo-2.6.0 下载后将dubbo-admin-2.6.0达成war包 2./docs/dubbo-admin/dubbo-admin-2.6.0.war获取war包 3.获取后 将war包放在tomcat的webapp目录 4.启动 window startup.bat linux ./bin/startup.sh 启动 -- 记得安装zk客户端才可以启动成功 5.访问 http://端口号:8080/dubbo-admin-2.6.0/ 可成功 6.账号密码 root/root ================================================ FILE: docs/dubbo-zk.md ================================================ ### dubbo + zk 使用与进阶 有问题或者宝贵意见联系我的QQ,非常希望你的加入! >目标 (希望大家仔细研究dubbo文档 源码分析正在更新中打算实现自己的rpc框架 请看dubbo-die ) http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-method.html dubbo文档地址 mapper 文件记得 在pom里面配置否则无法访问除了resources的mapper文件 ![配置图解](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo1.png) **1.如何利用dubbo 进行服务降级 ?** 一些服务降级措施,当服务提供端某一个非关键的服务出错时候,dubbo可以对消费端的调用进行降级,这样服务消费端就避免了在去调用出错的服务提供端,而是使用自定义的返回值直接在在本地返回 **2.springboot + dubbo 配置 ?** ![像注册中心写入动态覆盖配置规则](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo2.png) 可以通过服务降级功能临时屏蔽某个出错的非关键服务,并定义降级后的返回策略 ![像注册中心写入动态覆盖配置规则](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo3.png) **3.使用方式 ?** 在dubbo的页面 可以手动 更改自己想要的效果,也可以更改返回值!点击overrides 更改 ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo4.png) **4.解析** MockClusterInvoker 正常 ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo5.png) force ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo6.png) fail ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo7.png) impl ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo8.png) **5.参数含义** ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo9.png) ------------------------------------------------------------------------------------------------------ **6.自定义服务降级** ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo10.png) **7.自定义服务降级---类 必须为service加上mock** ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/dubbo11.png) ================================================ FILE: docs/fenbushi-tcc.md ================================================ ### 分布式事务 有问题或者宝贵意见联系我的QQ,非常希望你的加入! >目标 (希望大家仔细研究redis.conf配置文件-本文很多基础的一带而过) 1.事务简介 2.分布式事务的前世今生 3.分布式事务解决方案 4.主流分布式事务框架介绍 整理大部分常用的场景与使用,如果有疑问或者你不懂的地方请联系我! #### 1 分布式事务 >1.将多个节点的事务看成一个整体处理 >2.分布式事务由事务参与者,资源服务器,事务管理器等组成 >3.常见的分布式事务的例子: 支付,下订单等 >4.两段式事务和三段式事务(2pc,3pc) 基于XA的分布式事务 基于消息的最终一致性方案 TCC编程式补偿性方案 **redis分布式锁解决什么问题** 1.一个进程中的多个线程,多个线程并发访问同一个资源的时候,如何解决线程安全问题。 2.一个分布式架构系统中的两个模块同时去访问一个文件对文件进行读写操作 3.多个应用对同一条数据做修改的时候,如何保证数据的安全性 在但一个进程中,我们可以用到synchronized、lock之类的同步操作去解决,但是对于分布式架构下多进程的情况下, 如何做到跨进程的锁。就需要借助一些第三方手段来完成 **设计一个分布式所需要解决的问题,分布式锁解决方案(数据库方案)** 数据库解决方式,创建一个表叫做LOCK表 lock( id int(11) methodName varchar(100),--锁定的方法名称 memo varchar(1000) modifyTime timestamp unique key mn (method) --唯一约束 ) 在执行方法的时候,获取锁的伪代码 或者for update行锁 或者 乐观锁方式也是可以的 try{ exec insert into lock(methodName,memo) values(‘method’,’desc’); return true; }Catch(DuplicateException e){ return false; } 释放锁: delete from lock where methodName=’’; **(数据库方案)存在的问题以及思考** 1.锁没有失效时间,一旦解锁操作失败,就会导致锁记录一直在数据库中,其他线程无法再获得到锁 2.锁是非阻塞的,数据的insert操作,一旦插入失败就会直接报错。没有获得锁的线程并不会进入排队队列 要想再次获得锁就要再次触发获得锁操作 3.锁是非重入的,同一个线程在没有释放锁之前无法再次获得该锁 **ZK方案** ZK方案实现之前你要先了解ZK关于他的节点的几个特性: 有序节点:假如当前有一个父节点为/lock,我们可以在这个父节点下面创建子节点;zookeeper提供了一个可选的有序特性 例如我们可以创建子节点“/lock/node-”并且指明有序,那么zookeeper在生成子节点时会根据当前的子节点数量自动添加整数序号 也就是说如果是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一个节点则为/lock/node-0000000001,依次类推 临时节点:客户端可以建立一个临时节点,在会话结束或者会话超时后,zookeeper会自动删除该节点 事件监听:在读取数据时,我们可以同时对节点设置事件监听,当节点数据或结构变化时,zookeeper会通知客户端 当前zookeeper有如下四种事件: 1)节点创建 2)节点删除 3)节点数据修改 4)子节点变更 获取分布式锁的流程 ------- 假设所空间的根节点为/lock 1.客户端连接zookeeper,并在/lock下创建临时的且有序的子节点 第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推 2.--避免羊群效应--客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点, 如果是则认为获得锁,否则监听刚好在自己之前一位的子节点删除消息,获得子节点变更通知后重复此步骤直至获得锁 3.实行业务代码 4.流程完成后,删除对应的子节点并释放锁 (Watch机制) 对应分布式开源包Curator ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/zk.png) **Redis分布式锁方案** Redis 中有许多的命令都可以实现分布式锁,但是比较常用的是SETNX这个命令来实现 有多种方案代码: 1.获取锁,释放锁 代码在redismanager 里面 (简单版) ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/redislock1.png) ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/redislock2.png) closeOrder也有 不过是另一种!比较复杂!! 加入时间对比如果当前时间已经大与释放锁的时间 说明已经可以释放这个锁重新在获取锁,setget方法可以把之前的锁去掉在重新获取,旧值在于之前的 值比较,如果无变化说明这个期间没有人获取或者操作这个redis锁,则可以重新获取 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/redislock3.png) redis有成熟的框架redission **Redis多路复用机制(看不看都行)** linux的内核会把所有外部设备都看作一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令, 返回一个 file descriptor(文件描述符)。对于一个socket的读写也会有响应的描述符,称为socketfd(socket 描述符)。 而IO多路复用是指内核一旦发现进程指定的一个或者多个文件描述符IO条件准备好以后就通知该进程 IO多路复用又称为事件驱动,操作系统提供了一个功能,当某个socket可读或者可写的时候,它会给一个通知。 当配合非阻塞socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据。 操作系统的功能通过select/pool/epoll/kqueue之类的系统调用函数来使用,这些函数可以同时监视多个描述符的读写就绪情况 ,这样多个描述符的I/O操作都能在一个线程内并发交替完成,这就叫I/O多路复用,这里的复用指的是同一个线程 多路复用的优势在于用户可以在一个线程内同时处理多个socket的 io请求。达到同一个线程同时处理多个IO请求的目的。 而在同步阻塞模型中,必须通过多线程的方式才能达到目的 **Redis(2.6以后)--lua脚本** 1.减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行 2.原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。换句话说,编写脚本的过程中无需担心会出现竞态条件 3.复用性,客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑 4.脚本可以通过return 来返回客户端 例子: 利用lua脚本进行电话号或则IP限流 实例 具体请看 redislua类 KEYS[1] ARGV[1] ARGV[2] key 参数1 参数2 local num=redis.call('incr',KEYS[1]) if tonumber(num)==1 then redis.call('expire',KEYS[1],ARGV[1]) return 1 elseif tonumber(num)>tonumber(ARGV[2]) then return 0 else return 1 end **Redis(2.6以后)--lua--EVALSHA命令** 考虑到我们通过eval执行lua脚本,脚本比较长的情况下,每次调用脚本都需要把整个脚本传给redis 比较占用带宽。为了解决这个问题,redis提供了EVALSHA命令允许开发者通过脚本内容的SHA1摘要来执行脚本。该命令的用法和EVAL一样, 只不过是将脚本内容替换成脚本内容的SHA1摘要 1. Redis在执行EVAL命令时会计算脚本的SHA1摘要并记录在脚本缓存中 2. 执行EVALSHA命令时Redis会根据提供的摘要从脚本缓存中查找对应的脚本内容 如果找到了就执行脚本,否则返回“NOSCRIPT No matching script,Please use EVAL” **Redis(2.6以后)--lua脚本运行限制** redis的脚本执行是原子的,即脚本执行期间Redis不会执行其他命令 所有的命令必须等待脚本执行完以后才能执行。为了防止某个脚本执行时间过程导致Redis无法提供服务 Redis提供了lua-time-limit参数限制脚本的最长运行时间--默认是5秒钟 当脚本运行时间超过这个限制后,Redis将开始接受其他命令但不会执行(以确保脚本的原子性),而是返回BUSY的错误 在第一个窗口中执行lua脚本的死循环 eval “while true do end” 0 在第二个窗口中运行get hello 最后第二个窗口的运行结果是Busy, 可以通过script kill命令终止正在执行的脚本 如果当前执行的lua脚本对redis的数据进行了修改,比如(set)操作,那么script kill命令没办法终止脚本的运行, 因为要保证lua脚本的原子性。如果执行一部分终止了,就违背了这一个原则 在这种情况下,只能通过 shutdown nosave命令强行终止 **Redis(2.6以后)--lua分布式锁** ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/lualock.png) ================================================ FILE: docs/fenbushi.md ================================================ ### 分布式系统 有问题或者宝贵意见联系我的QQ,非常希望你的加入! > 分布式系统历程----1 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/fenbushi1.png) > 分布式系统历程----2 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/fenbushi2.png) > 分布式系统历程----3 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/fenbushi3.png) > 分布式系统历程----4 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/fenbushi4.png) > 分布式系统历程----5 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/fenbushi5.png) > 分布式系统历程----6 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/fenbushi6.png) > 分布式系统历程----7 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/fenbushi7.png) ================================================ FILE: docs/jemter-solve.md ================================================ ### 如何利用jmeter进行压测 ### 我的服务配置较低大数据量请在自己的服务器上搞下不然就崩了 有问题或者宝贵意见联系我的QQ,非常希望你的加入! >目标 (希望大家仔细研究redis.conf配置文件-本文很多基础的一带而过) 1.如何对秒杀生成大数据量对应的用户id和token来进行压测 2.利用jmeter进行接口压测 我这个版本只是简单的测试,你仍然需要把一些接口安全的放开或者自己写一个没有安全性防刷一类的接口测试性能 如果有疑问或者你不懂的地方请联系我! #### 1 利用jmeter进行接口压测 (jmeter3.0 jdk1.7 版本以上需1.8 版本在tools里面) **秒杀生成大数据量对应的用户id和token** 在后端写模拟前端请求计算出不同的用户对应的token , 在UserUtil类里面 生成文件格式: ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter4.png) 代码类: ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter2.png) ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter3.png) 利用这个类可以生成大数据量的userId和token当前也可以自己改装生成你想要的 **利用jmeter进行接口压测** 1.点击右键生成线程组一类的 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter5.png) 2.右键线程组选择配置原件并定义http默认值 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter6.png) 3.右键监听器可以生成聚合报告等一类的 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter7.png) 4.右键线程组添加sampler 添加请求http请求具体情况更具实际的来 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter9.png) 5.右键线程组添加CSV DATA Set Config 设置用户参数和token 把生成的路径引进来 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/jmeter8.png) ================================================ FILE: docs/jvm-goods.md ================================================ ### 生产内存环境 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ## 前言 注重实践,不会长篇大论,纯属浪费大家时间!属于进阶文章,感谢你的支持! 解决问题: |_ 1.生产环境发生了内存溢出该如何处理 |_ 2.生产环境应该给服务器分配多少的内存 |_ 3.如何对垃圾回收起的性能进行调优 |_ 4.生产环境CPU的负载飙高应该如何处理 |_ 5.生产环境因该给应用分配多少的线程合适 |_ 6.不加log如何确定请求是否执行到某一段的代码 |_ 7.实时查看某个方法的入参与返回值 |_ 8.JVM的字节码实操 |_ 9.循环体中字符串拼接为什么效率很低 |_ 10.string常量池怎么回事 |_ 11.用字节码分析 i++,++i 到底哪种效率高 项目实战收获: |_ 1.熟练使用各种监控和调试工具 |_ 2.从容应对生产环境的各种调试和性能 |_ 3.熟悉JVM字节码指令 |_ 4.深入理解JVM自动回收机制学会GC调优 |_ 5.基于JDK命令行的监控 |_ JVM的参数类型 |_ 查看JVM运行时的参数 |_ Jstat查看JVM统计信息 |_ 演示内存溢出 |_ 导出内存映像文件 |_ MAT分析内存溢出 |_ jstack与线程的状态 |_ jstack实战死循环与锁 |_ 6.基于JVisualVM的可视化工具 |_ 监控本地java进程 |_ 监控远程java进程 |_ 7.基于Btrace的监控调试基于Btrace的监控调试 |_ Btrace入门 |_ 拦截器构造函数,同名函数 |_ 拦截器返回值,异常,行号 |_ 拦截器复杂参数,环境变量,正则匹配拦截 |_ 注意事项 |_ 8.tomcat的性能监控调优 |_ tomcat远程debug |_ tomcat-manager监控 |_ psi-probe监控 |_ tomcat优化 |_ 9.nginx的监控调优 |_ nginx的监控调优 |_ ngx_http_stub_status监控连接信息 |_ ngxtop监控请求信息 |_ nginx-rrd图形化监控 |_ nginx优化 |_ 10.jvm+gc调优 |_ JVM的内存结构以及各个分区 |_ 常见垃圾回收算法 |_ 垃圾回收期调优 |_ 如何分析内存日志 |_ 垃圾回收器 |_ GC日志格式详解 |_ ParallelGC调优 |_ G1调优 **基于JDK命令行工具监控** |_ JVM参数类型 |_ 运行时JVM参数查看 |_ jstat查看虚拟机统计信息 |_ jmap + MAT实战内存溢出 |_ jstack 实战死锁循环与死锁 | ID | Problem | Article | | --- | --- | :--- | | 000 |JVM参数类型 | 三种: 标准参数 , X参数 ,XX 参数 | | 001 |如何对本项目进行jmeter压测 | [解决思路](https://raw.githubusercontent.com/qiurunze123/imageall/master/miaosha.png) | ================================================ FILE: docs/linux.md ================================================ ### 秒杀nginx优化 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ##要求: >目标 1.并发优化 2.KeepALive长连接优化 3.压缩优化 4.配置缓存 #### [/docs/tools/nginx nginx优化相关包](/docs/tools) 安装:cd yum install -y gcc gcc-c++ ./configure --prefix=/usr/local/nginx --with-pcre=/home/qiurunze/下载/pcre-8.38 --with-http_stub_status_module --with-http_gzip_static_module --add-module=/home/qiurunze/下载/ngx_cache_purge-2.3 make make install ps -ef | grep nginx ./sbin/nginx -s reload http://nginx.org/en/docs/ 1.工作线程数和并发连接数 worker_processes 4; #cpu,如果nginx单独在一台机器上 worker_processes auto; events { worker_connections 4096;#每一个进程打开的最大连接数,超出了log中会有记录 multi_accept on; #可以一次建立多个连接 use epoll; } worker_rlimit_nofile 10240;每个进程打开的最大的文件数,受限于操作系统: vi /etc/security/limits.conf * hard nofile 102400 * soft nofile 102400 * soft core unlimited * soft stack 10240 2.操作系统优化 配置文件/etc/sysctl.conf sysctl -w net.ipv4.tcp_syncookies=1#防止一个套接字在有过多试图连接到达时引起过载 sysctl-w net.core.somaxconn=1024#默认128,连接队列 sysctl-w net.ipv4.tcp_fin_timeout=10 # timewait的超时时间 sysctl -w net.ipv4.tcp_tw_reuse=1 #os直接使用timewait的连接 sysctl -w net.ipv4.tcp_tw_recycle = 0 #回收禁用 3.Keepalive长连接 Nginx与upstream server: upstream server_pool{ server localhost:8080 weight=1 max_fails=2 fail_timeout=30s; keepalive 300; #300个长连接 } 同时要在location中设置: location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } 客户端与nginx(默认是打开的): 4.keepalive_timeout 60s; #长连接的超时时间 keepalive_requests 100; #100个请求之后就关闭连接,可以调大 keepalive_disable msie6; #ie6禁用启用压缩 gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_proxied any; gzip_types text/html text/plain application/x-javascript application/javascript text/css application/xml gzip_vary on; #Vary: Accept-Encoding gzip_static on; #如果有压缩好的 直接使用 5.状态监控 location = /nginx_status { stub_status on; access_log off; allow ; deny all; } 输出结果: Active connections: 1 server accepts handled requests 17122 17122 34873 Reading: 0 Writing: 1 Waiting: 0 Active connections:当前实时的并发连接数 accepts:收到的总连接数, handled:处理的总连接数 requests:处理的总请求数 Reading:当前有都少个读,读取客户端的请求 Writing:当前有多少个写,向客户端输出 Waiting:当前有多少个长连接(reading + writing) reading – nginx reads request header writing – nginx reads request body, processes request, or writes response to a client waiting – keep-alive connections, actually it is active - (reading + writing) 6.实时请求信息统计ngxtop https://github.com/lebinh/ngxtop (1)安装python-pip yum install epel-release yum install python-pip (2)安装ngxtop pip install ngxtop (3)使用 指定配置文件: ngxtop -c ./conf/nginx.conf 查询状态是200: ngxtop -c ./conf/nginx.conf --filter 'status == 200' 查询那个ip访问最多: ngxtop -c ./conf/nginx.conf --group-by remote_addr ----------------------------------------------------------------------------- nginx.conf配置文件 user www; worker_processes 4;#取决于cpu error_log logs/error.log; pid logs/nginx.pid; worker_rlimit_nofile 10240; #每个进程打开的最大的文件数,受限于操作系统/etc/security/limits.conf events { worker_connections 10240;#每一个进程打开的最大连接数,超出了log中会有记录 multi_accept on; #可以一次建立多个连接 use epoll; } http { include mime.types; default_type application/octet-stream; server_tokens off; #隐藏版本号 client_max_body_size 10m; #文件上传需要调大 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; #默认写日志:打开文件写入关闭,max:缓存的文件描述符数量,inactive缓存时间,valid:检查时间间隔,min_uses:在inactive时间段内使用了多少次加入缓存 open_log_file_cache max=200 inactive=20s valid=1m min_uses=2; sendfile on; tcp_nopush on; #与浏览器的长连接 keepalive_timeout 65;#长连接超时时间 keepalive_requests 500;#500个请求以后,关闭长连接 keepalive_disable msie6; # 启用压缩 gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_proxied any; gzip_types text/plain application/x-javascript application/javascript text/css application/xml; gzip_vary on; #Vary: Accept-Encoding gzip_static on; #如果有压缩好的 直接使用 #超时时间 proxy_connect_timeout 5; #连接proxy超时 proxy_send_timeout 5; # proxy连接nginx超时 proxy_read_timeout 60;# proxy响应超时 # 开启缓存,2级目录 proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=20g; proxy_ignore_headers X-Accel-Expires Expires Cache-Control; proxy_hide_header Cache-Control; proxy_hide_header Pragma; #反向代理服务器集群 upstream server_pool{ server localhost:8080 weight=1 max_fails=2 fail_timeout=30s; server localhost:8081 weight=1 max_fails=2 fail_timeout=30s; keepalive 200; # 最大的空闲的长连接数 } server { listen 80; server_name localhost 192.168.220.133; location / { #长连接 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; #Tomcat获取真实用户ip proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://server_pool; } # 状态监控 location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; allow 192.168.220.133; deny all; } #用于清除缓存 location ~ /purge(/.*) { allow 127.0.0.1; allow 192.168.220.133; deny all; proxy_cache_purge cache_one $host$1$is_args$args; } # 静态文件加缓存 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css|html|htm)?$ { expires 1d; proxy_cache cache_one; proxy_cache_valid 200 304 1d; proxy_cache_valid any 1m; proxy_cache_key $host$uri$is_args$args; proxy_pass http://server_pool; } } } ================================================ FILE: docs/maven-wrapper.md ================================================ ### maven wrapper 下载项目, 切换的项目根目录 ```bash Linux/Mac: > cd miaosha/ > ./mvnw clean install Windows: > mvnw.cmd clean install ``` 运行以上命令相关依赖便会安装完毕 启动GeekQMainApplication主类即可 若有对于./mvnw 不了解的请点击下方链接介绍 > 传统maven的使用流程 1. 传统使用maven需要先到官网上下载. 2. 配置环境变量把mvn可执行文件路径加入到环境变量,以便之后使用直接使用mvn命令. 3. 另外项目pom.xml文件描述的依赖文件默认是下载在用户目录下的.m2文件下的repository目录下. 4. 再次,如果需要更换maven的版本,需要重新下载maven并替换环境变量path中的maven路径. > maven-wrapper,会获得以下特性 执行mvnw比如./mvnw clean ,如果本地没有匹配的maven版本,直接会去下载maven,放在用户目录下的.m2/wrapper中 并且项目的依赖的jar包会直接放在项目目录下的repository目录,这样可以很清晰看到当前项目的依赖文件。 如果需要更换maven的版本,只需要更改项目当前目录下.mvn/wrapper/maven-wrapper.properties的distributionUrl属性值,更换对应版本的maven下载地址。mvnw命令就会自动重新下载maven。 可以说带有mvnw文件的项目,除了额外需要配置 java环境外,只需要使用本项目的mvnw脚本就可以完成编译,打包,发布等一系列操作。 > 如何使用呢? 通常我们在使用maven的时候会执行如下一些命令: mvn clean mvn install mvn package ... 使用maven wrapper之后只需打开terminal 执行如下等价命令即可: linux: ./mvnw clean ./mvnw install ./mvnw package ... windows: mvnw.cmd clean mvnw.cmd install mvnw.cmd package ... > Get Started! 因此大家在下载项目代码之后, 只需要执行 ./mvn clean install maven warpper 便会自动为该项目构建maven环境. 当然如果大家用的IDE是idea 那么依然也可以使用右上方的MavenProject Panel 鼠标触发各个Task ================================================ FILE: docs/mybatis-code.md ================================================ ### mybatis使用与总结 有问题或者宝贵意见联系我的QQ,非常希望你的加入! > mybatis 使用总结 #### resultType 和 resultMap MyBatis的每一个查询映射的返回类型都是ResultMap, 只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性, 而当我们提供的返回类型是resultMap的时候,将数据库中列数据复制到对象的相应属性上,可以用于复制查询,两者不能同时用。 #### typeAliases类型命名 存在的意义在于减少类的完全限定名的冗余 _user可以用在任何需要com.geekq.miaosha.mybatis.User ### 当实体类中的属性名和表中的字段名不一致时使用MyBatis进行查询操作时无法查询出相应的结果的问题以及针对问题采用的两种办法 解决办法一: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致, 这样就可以表的字段名和实体类的属性名一一对应上了,这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的 解决办法二: 通过来映射字段名和实体类属性名的一一对应关系。 这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。 ### 为什么order by 要用${xxx} 而不用 #{} 对于形如#{variable} 的变量,Mybatis会将其视为字符串值,在变量替换成功后,缺省地给变量值加上引号。"variable" (2)对于形如${variable}的变量,Mybatis会将其视作直接变量,即在变量替换成功后,不会再给其加上引号。 variable 所以在动态sql中,#{variable} 需要去掉 "",比如正常sql赋值一般是这样的and name= #{name},因为是=赋值,所以会获取内容,去掉"" ${variable}可以直接使用,比如order by ${name} 传入的直接是name,不带双引号,可以直接使用, 并且order by不是 =赋值,所以如果直接order by #{name},结果是order by "name",自然无法执行了 ### 如何打印sql日志 ? xml方式 配置方式: #打印mybatis sql log4j.logger.com.ibatis=DEBUG log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG log4j.logger.Java.sql.Connection=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG ### 动态sql标签 if choose (when, otherwise) trim (where, set) foreach ### 如何使用mybatis-generator:generate pom 配置: org.mybatis.generator mybatis-generator-maven-plugin 1.3.2 true false mysql mysql-connector-java 5.1.21 ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/mybatis1.png) ![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/mybatis2.png) ### generatorConfig.xml 内容解析? 已在其中备注,详细内容请见generatorConfig.xml ### xml映射文件都会有一个dao接口,工作原理? Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。 Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象, 代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。 ### ================================================ FILE: docs/mysql-2.md ================================================ ### mysql数据库设计与优化与架构 模拟场景(京东商城) 任何优化多需要场景,本次所有的场景为京东商城的数据库设计模拟! 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ##简介: 设计: 1.常见业务处理 2.执行计划分析 3.如何优化分页查询示例 4.如何删除重复数据示例 5.如何进行分区间数据统计显示 6.捕获有问题的sql慢查日志 **执行计划能够告诉我们什么** 1.sql如何使用索引 2.链接查询的执行顺序 3.查询扫描数据行数 **执行计划内容** ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql1.png) ID列:数据为一组数字表示执行select语句的顺序 id值相同的时候执行顺序由上至下 id值越大优先级越高,越先被执行 ID列中的如果数据为一组数字,表示执行SELECT语句的顺序;如果为NULL,则说明这一行数据是由另外两个SQL语句进行 UNION操作后产生的结果集 SELECT_TYPE |_ SIMPLE不包含子查询或者是UNION操作的查询 |_ PRIMARY 查询中如果包含任何子查询,那么最外层的查询则被标记为 PRIMARY |_ SUBQUERY select 列表中的子查询 |_ DEPENDENT 依赖外部结果的子查询 |_ SUBQUERY 依赖外部结果的子查询 |_ UNION Union操作的第二个或是之后的查询的值为union |_ DEPENDENT UNION 当UNION作为子查询时,第二或是第二个后的查询的select_type值 |_ UNION RESULT UNION产生的结果集 |_ DERIVED 出现在FROM子句中的子查询 TABLE |_ 所在表的名称,如果表取了别名,则显示的是别名 |_ : 由ID为M,N查询union产生的结果集 |_ / :由ID为N的查询产生的结果 PARTITIONS 分区表 查询匹配的记录来自哪一个分区 对于分区表,显示查询的分区ID 对于非分区表,显示为NULL TYPE列 |_ system 这是const联接类型的一个特例,当查询的表只有一行时使用 |_ const 表中有且只有一个匹配的行时使用,如对主键或是唯一索引的查询,这是效率最高的联接方式 |_ eq_ref 唯一索引或主键索引查询,对应每个索引键,表中只有一条记录与之匹配 |_ ref 非唯一索引查找,返回匹配某个单独值的所有行 |_ ref_or_null 类似于ref类型的查询,但是附加了对NULL值列的查询 |_ index_merge 该联接类型表示使用了索引合并优化方法 |_ range 索引范围扫描,常见于between、>、<这样的查询条件 |_ index FULL index Scan 全索引扫描,同ALL的区别是,遍历的是索引树 |_ ALL FULL TABLE Scan 全表扫描,这是效率最差的联接方式 Extra列 |_ Distinct 优化distinct操作,在找到第一个匹配的元素后即停止查找 |_ Not exists 使用not exists来优化查询 |_ Using filesort 使用额外操作进行排序,通常会出现在order by或group by查询中 |_ Using index 使用了覆盖索引进行查询 |_ Using temporary MySQL需要使用临时表来处理查询,常见于排序,子查询,和分组查询 |_ Using where 需要在MySQL服务器层使用WHERE条件来过滤数据 |_ select tables optimized away 直接通过索引来获得数据,不用访问表,这种情况通常效率是最高的 POSSIBLE_KEYS列 |_ 指出MySQL能使用哪些索引来优化查询 |_ 查询列所涉及到的列上的索引都会被列出,但不一定会被使用 KEY列 |_查询优化器优化查询实际所使用的索引 |_如果表中没有可用的索引,则显示为NULL |_如果查询使用了覆盖索引,则该索引仅出现在Key列中 KEY_LEN列 |_ 显示MySQL索引所使用的字节数,在联合索引中如果有3列,假如3列字段总长度为100个字节 Key_len显示的可能会小于100字节,比如30字节 这就说明在查询过程中没有使用到联合索引的所有列,只是利用到了前面的一列或2列 |_ 表示索引字段的最大可能长度 |_ Key_len的长度由字段定义计算而来,并非数据的实际长度 Ref列 |_ 表示当前表在利用Key列记录中的索引进行查询时所用到的列或常量 |_ |_ rows列 |_ 表示MySQL通过索引的统计信息,估算出来的所需读取的行数(关联查询时,显示的是每次嵌套查询时所需要的行数 |_ Rows值的大小是个统计抽样结果,并不十分准确 Filtered列 |_ 表示返回结果的行数占需读取行数的百分比 |_ Filtered列的值越大越好(值越大,表明实际读取的行数与所需要返回的行数越接近) |_ Filtered列的值依赖统计信息,所以同样也不是十分准确,只是一个参考值 执行计划的限制 |_ 无法展示存储过程,触发器,UDF对查询的影响 |_ 无法使用EXPLAIN对存储过程进行分析 |_ 早期版本的MySQL只支持对SELECT语句进行分析 ---------------------------------------------------- 如何删除重复数据 删除评论表中的对同一个商品的重复评论,只保留最早的一条 |--- 查看是否存在对于同一订单同一商品的重复评论,如果存在,进行后续步骤 查询语句: SELECT order_id,product_id,COUNT(*) FROM product_comment GROUP BY order_id,product_id HAVING COUNT(*) > 1; |--- 备份product_comment表(避免误删除的情况) CREATE TABLE bak_product_comment_190108 AS SELECT * FROM product_comment; 错误代码:1786 Statement violates GTID consistency:CREATE TABLE ... SELECT. 则换用下面的语句 CREATE TABLE bak_product_comment_190108 AS LIKE product_comment; INSERT INTO bak_product_comment_190108 SELECT * FROM product_comment; 错误代码:1786 Statement violates GTID consistency:CREATE TABLE ... SELECT. 错误原因 这是因为在5.6及以上的版本内,开启了 enforce_gtid_consistency=true 功能导致的,MySQL官方解释说当启用 enforce_gtid_consistency 功能的时候,MySQL只允许能够保障事务安全,并且能够被日志记录的SQL语句被执行,像create table … select 和 create temporarytable语句,以及同时更新事务表和非事务表的SQL语句或事务都不允许执行。 解决办法 |---- 修改 : SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = off; 配置文件中 : ENFORCE_GTID_CONSISTENCY = off; |---- create table xxx as select 的方式会拆分成两部分。 create table xxxx like data_mgr; insert into xxxx select *from data_mgr; 如果表数据量比较大,则使用mysql dump的方式导出成文件进行备份 |---- 删除同一订单的重复评论 删除语句: DELETE a FROM product_comment a JOIN( SELECT order_id,product_id,MIN(comment_id) AS comment_id FROM product_comment GROUP BY order_id,product_id HAVING COUNT(*) > 1 ) b on a.order_id = b.order_id AND a.product_id = b.product_id AND a.comment_id > b.comment_id; 分区间统计 统计消费总金额大于1000元的,800到1000元的,500到800元的,以及500元以下的人数 SELECT COUNT(CASE WHEN IFNULL(total_money,0) >= 1000 THEN a.customer_id END) AS '大于1000' ,COUNT(CASE WHEN IFNULL(total_money,0) >= 800 AND IFNULL(total_money,0)<1000 THEN a.customer_id END) AS '800~1000' ,COUNT(CASE WHEN IFNULL(total_money,0) >= 500 AND IFNULL(total_money,0)<800 THEN a.customer_id END) AS '500~800' ,COUNT(CASE WHEN IFNULL(total_money,0) < 500 THEN a.customer_id END) '小于500' FROM mc_userdb.customer_login a LEFT JOIN ( SELECT customer_id,SUM(order_money) AS total_money FROM mc_orderdb.order_master GROUP BY customer_id ) b ON a.customer_id = b.customer_id **for example测试表分析执行计划 (联合索引和单列索引)** CREATE TABLE `miaosha_mysql_test` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `userId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '用户id', `mobile` varchar(24) NOT NULL DEFAULT '' COMMENT '手机号码', `month` varchar(32) DEFAULT NULL COMMENT '月份', `createTime` datetime DEFAULT NULL COMMENT '创建时间', `overTime` datetime DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`), KEY `联合索引` (`userId`,`mobile`,`month`) ) ENGINE=InnoDB AUTO_INCREMENT=71185 DEFAULT CHARSET=utf8 COMMENT='测试' 建立联合索引的列userId,mobile,month 三个建立联合索引 EXPLAIN SELECT * FROM `miaosha_mysql_test` WHERE userid='2222' and mobile='166011' ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql2.png) 无索引可用 EXPLAIN SELECT * FROM `miaosha_mysql_test` WHERE mobile='166011' ; ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql3.png) 有索引可用 EXPLAIN SELECT * FROM `miaosha_mysql_test` WHERE userid='2222' or mobile='166011' ; ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql4.png) 有索引可用 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql5.png) 有索引可用 当然这才是正确的用法!!! ---------- ----------- ----------- -------------- **创建三个单列的索引** CREATE INDEX useridsingle ON miaosha_mysql_test(userid); CREATE INDEX mobilesingle ON miaosha_mysql_test(mobile); CREATE INDEX monthsingle ON miaosha_mysql_test(month); EXPLAIN SELECT * FROM `miaosha_mysql_test` WHERE userid='2222' and mobile='166011' and month=1; ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql7.png) 只是用了useridsingle 有索引可用 EXPLAIN SELECT * FROM `miaosha_mysql_test` WHERE mobile='13281899972' AND month='2018-04' ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql8.png) EXPLAIN SELECT * FROM `miaosha_mysql_test` WHERE userid='2222' OR mobile='13281899972' ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/mysql9.png) 有索引可用 都用上了 **多个单列索引在多条件查询时只会生效第一个索引!所以多条件联合查询时最好建联合索引!** **最左前缀原则:** |_在创建联合索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。这样的话扩展性较好 |_比如 userid 经常需要作为查询条件,而 mobile 不常常用 |_则需要把 userid 放在联合索引的第一位置,即最左边 |_第一个字段是范围查询需要单独建一个索引 **同时存在联合索引和单列索引(字段有重复的),这个时候查询mysql会怎么用索引呢** 当一个表有多条索引可走,那么会根据优化器的查询成本来选择走哪个索引 联合索引本质: 当创建(a,b,c)联合索引时,相当于创建了(a)单列索引,(a,b)联合索引以及(a,b,c)联合索引 想要索引生效的话,只能使用 a和a,b和a,b,c三种组合,当然a,c也可以但是只用到了a 1.需要加索引的字段,要在where条件中 2、数据量少的字段不需要加索引;因为建索引有一定开销,如果数据量小则没必要建索引(速度反而慢) 3、如果where条件中是OR关系,加索引不起作用 4、联合索引比对每个列分别建索引更有优势,因为索引建立得越多就越占磁盘空间, 在更新数据的时候速度会更慢。另外建立多列索引时,顺序也是需要注意的, 应该将严格的索引放在前面,这样筛选的力度会更大,效率更高。 ================================================ FILE: docs/mysql-3.md ================================================ ### 数据库备份和恢复 + 数据库架构变迁 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ## 简介: ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/MySQLGood.png) ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/sql.jpg) **详情请下载** [xmind总结](/docs/MySQL性能优化.xmind) | ================================================ FILE: docs/mysql-master-slave.md ================================================ ### 分库分表及mycat的整理实操(未整理马上更新) 本文章安排目标: 1. 对于存储层的压力知道如何去提供解决方案和思路 2. 对分库分表的常用手段有全面了解 3. 了解Mysql的主从及binlog 4. 知道Mycat及其他相似的中间件 5. Mycat是什么 6. Mycat中的核心概念及配置文件分析 7. 水平分表实战(单库、跨库) 8. Mycat读写分离实战 9. Mycat 全局序列号 10. Mycat常用分片规则 ##思路(3why??) **为什么要进行分库分表** 为什么要分库分表、 超大容量问题 性能问题 如何去做到 垂直切分、 水平切分 1. 垂直分库; 解决的是表过多的问题 2. 垂直分表; 解决单表列过多的问题 水平切分; 大数据表拆成小表 常见的拆分策略 垂直拆分(er分片) 水平拆分 一致性hash 范围切分 可以按照ID 日期拆分 拆分以后带来的问题 跨库join的问题 1. 设计的时候考虑到应用层的join问题。 2. 在服务层去做调用; A服务里查询到一个list for(list){ bservice.select(list); } 3. 全局表 1. 数据变更比较少的基于全局应用的表 2. 4. 做字段冗余(空间换时间的做法) 订单表。 商家id 商家名称 商家名称变更- 定时任务、任务通知 跨分片数据排序分页 唯一主键问题 用自增id做主键 UUID 性能比较低 snowflake mongoDB zookeeper 数据库表 分布式事务问题 多个数据库表之间保证原子性 性能问题; 互联网公司用强一致性分布式事务比较少 分库分表最难的在于业务的复杂度; 前提: 水平分表的前提是已经存在大量的业务数据。而这个业务数据已经渗透到了各个应用节点 如何权衡当前公司的存储需要优化 1. 提前规划(主键问题解决、 join问题) 2. 当前数据单表超过1000W、每天的增长量持续上升 Mysql的主从 数据库的版本5.7版本 安装以后文件对应的目录 mysql的数据文件和二进制文件: /var/lib/mysql/ mysql的配置文件: /etc/my.cnf mysql的日志文件: /var/log/mysql.log 140 为master 1. 创建一个用户’repl’,并且允许其他服务器可以通过该用户远程访问master,通过该用户去读取二进制数据,实现数据同步 create user repl identified by ‘repl; repl用户必须具有replication slave权限,除此之外其他权限都不需要 grant replication slave on *.* to ‘repl’@’%’ identified BY ‘repl’ ; 2. 修改140 my.cnf配置文件,在[mysqld] 下添加如下配置 log-bin=mysql-bin //启用二进制日志文件 server-id=130 服务器唯一ID 3. 重启数据库 systemctl restart mysqld sudo /etc/init.d/mysql start 4. 登录到数据库,通过show master status 查看master的状态信息 142 为slave 1. 修改142 my.cnf配置文件, 在[mysqld]下增加如下配置 server-id=132 服务器id,唯一 relay-log=slave-relay-bin relay-log-index=slave-relay-bin.index read_only=1 2. 重启数据库: systemctl restart mysqld 3. 连接到数据库客户端,通过如下命令建立同步连接 change master to master_log_file='mysql-bin 隆.000002',master_log_pos=154; error: ERROR 1794 (HY000): Slave is not configured or failed to initialize properly. You must at least set --server-id to enable either a master or a slave. Additional error messages can be found in the MySQL error log. 最后通过如下的操作解决的问题,具体原因还尚未清楚 CHANGE MASTER TO MASTER_HOST='39.107.245.253', MASTER_USER='repl', MASTER_PASSWORD='repl', MASTER_LOG_FILE='mysql-bin 隆.000001', MASTER_LOG_POS= 154; (1)登录数据库后,删除5张表,并重新导入脚本 use mysql drop table slave_master_info; drop table slave_relay_log_info; drop table slave_worker_info; drop table innodb_index_stats; drop table innodb_table_stats; --------------------- 2.重启数据库 change master to master_host='39.107.245.253', master_port=3306,master_user='repl',master_password='repl',master_log_file='mysql-bin 隆.000001',master_log_pos=154; 红色部分从master的show master status可以找到对应的值,不能随便写。 4. 执行 start slave 5. show slave status\G;查看slave服务器状态,当如下两个线程状态为yes,表示主从复制配置成功 Slave_IO_Running=Yes Slave_SQL_Running=Yes 主从同步的原理 1. master记录二进制日志。在每个事务更新数据完成之前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务 2. slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志 3. SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致 binlog: 用来记录mysql的数据更新或者潜在更新(update xxx where id=x effect row 0); 文件内容存储:/var/lib/mysql mysqlbinlog --base64-output=decode-rows -v mysql-bin.000001 查看binlog的内容 binlog的格式 statement : 基于sql语句的模式。update table set name =””; effect row 1000; uuid、now() other function row: 基于行模式; 存在1000条数据变更; 记录修改以后每一条记录变化的值 mixed: 混合模式,由mysql自动判断处理 修改binlog_formater,通过在mysql客户端输入如下命令可以修改 set global binlog_format=’row/mixed/statement’; 或者在vim /etc/my.cnf 的[mysqld]下增加binlog_format=‘mixed’ 主从同步的延时问题 主从同步延迟是怎么产生的 1. 当master库tps比较高的时候,产生的DDL数量超过slave一个sql线程所能承受的范围,或者slave的大型query语句产生锁等待 2. 网络传输: bin文件的传输延迟 3. 磁盘的读写耗时:文件通知更新、磁盘读取延迟、磁盘写入延迟 解决方案 1. 在数据库和应用层增加缓存处理,优先从缓存中读取数据 2. 减少slave同步延迟,可以修改slave库sync_binlog属性; sync_binlog=0 文件系统来调度把binlog_cache刷新到磁盘 sync_binlog=n 3. 增加延时监控 Nagios做网络监控 mk-heartbeat 5. Mysql的主从配置 6. 了解binlog及主从复制原理 ================================================ FILE: docs/mysql-mvcc.md ================================================ ### MVCC原理 Multi-Version Concurrency Control,翻译为中文即多版本并发控制,使用它来实现RR以及RC隔离级别下读取数据的隔离性。串行话可以理解为直接用锁,而读未提交可以理解成什么也不控制。 innodb为每一行记录都实现了三个隐藏字段 DB_ROW_ID 6个字节: 行标识 DB_TRX_ID 6个字节:删除、插入或者更新行的最后一个事物id,自动增长 DB_ROLL_PTR 7个字节:回滚指针 | #transaction 100 | #transaction 200 | #transaction 300 | #select 1 | #select 2 | | ---- | ---- |---- |---- |---- | | bengin | bengin | bengin | | update test set cl = '123' where id =1; | | | update test set cl = '123' where id =1; | | | | update account set name = 'lilei300' where id =1; | | | | commit; | | | | | select name from account where id=1; readview[100,200] 300 --> lilei300 | | update account set name = 'lilei1' where id =1; | | update account set name = 'lilei2' where id =1; | | | | | select name from account where id=1; readview[100,200] 300 --> lilei300 | | commit; | update account set name = 'lilei3' where id =1; | | | update account set name = 'lilei4' where id =1; | | | | | select name from account where id=1; readview[100,200] 300 --> lilei300 | select name from account where id=1; readview[200] 300 --> lilei2 | | | commit; | ![版本变更流程](imgs/mysql-mvcc-1.png) 操作的时候会生成事务id ①每条记录都会拼接trx_id(事务id)和roll_pointer(回滚指针)2个字段 ②每次操作会将就数据移动到undo log,修改后数据的回滚指针,指向undo log中这条数据 查询的时候会读取出ReadView(一致性视图):【未提交的事务id】数组+已创建的最大事务id 可重复读,会在事物中第一次读数据时生成readview 读已提交,会在事务中每次读取数据时生成readview 匹配规则: 1.当表中数据事务id < readview未提交事务最小值,数据可见 2.当表中数据事务id > readview最大事务id,说明本次事务开启时,表中数据事务都还没开启。 数据不可见 3.当表中数据事务id in readview未提交数组里,说明这个事务还未提交,不可见。 特殊的:如果事务是当前事务,依旧可见 4.当表中数据事务id > readview未提交数组里 || 当表中数据事务id < readview已创建的最大事务id 可见 删除算修改的一种特殊情况,会在undo log 的record header中记录下delete flag,如果被删除了,就忽略这条数据。 ![匹配规则](imgs/mysql-mvcc-2.png) ### MVCC & 2PL解决了部分幻读问题 主要参考https://www.zhihu.com/question/372905832,分别讲了MVCC和2PL(悲观锁,对应还有OCC乐观锁)解决的幻读问题 ps:幻读主要在insert,不可重复读主要在delete & update #### MVCC解决的幻读 阿里:http://mysql.taobao.org/monthly/2017/06/07/,这边文章是以mysql可重复度解决了幻读,但此情况还是出现了幻读的角度。我们反过来看mysql是如何通过MVCC解决部分幻读的 ![mvcc解决幻读](imgs/mysql-mvcc-3.png) 在这个案例中。如果mysql的可重复读不解决幻读问题。哪session1在第二次select中应该是可以查出session2插入的数据的。但是由于MVCC的存在,session2的事务id是大于session1中readview的最大事务的,所以我们是看不到session2插入的数据的,保证了此时的不可幻读。但是记住MVCC只是解决读问题。在update时 讲session2插入的数据的事务id更新成seesion1的事务id了,导致最后一次查询数据的事务id==当前事务id变成可见了。 #### 2PL解决部分幻读 美团:https://tech.meituan.com/2014/08/20/innodb-lock.html ![mvcc解决幻读](imgs/mysql-mvcc-4.png) 以我们的认知可重复不解决幻读问题,此时事务B的数据应该是能插入的,但实际上被阻塞了,这是因为事务A在执行update的时候加上了间隙锁 ![mvcc解决幻读](imgs/mysql-mvcc-5.png) 导致此时无法插入,需等事务A提交后释放锁(2PL第二步)才能插入。 ================================================ FILE: docs/mysql.md ================================================ ### mysql数据库设计与优化与架构 模拟场景(京东商城) 任何优化多需要场景,本次所有的场景为京东商城的数据库设计模拟! 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ##简介: 设计: 1.数据库开发规范的制定 2.数据库结构与设计 3.mysql执行计划的分析 4.mysql数据库的备份和恢复 5.mysql高性能高可用架构变迁 **场景说明** 用户登录->选购商品->加购物车->检查库存->提交订单->货到付款-- Y -- 发货 |N--订单付款 用户模块 -- 完成用户注册和登录验证 商品模块 -- 前后台商品管理和游览 订单模块 -- 订单和购物车的生成和管理 仓配模块 -- 仓库库存和物流的管理 **数据库设计规范** 逻辑设计 + 物理设计 1.数据库命名规范 2.数据库基本设计规范 3.数据库索引设计规范 4.数据库字段设计规范 5.数据库的sql开发规范 数据库操作行为规范(运维标准) 数据库设计规范 1.所有的数据库对象名称必须使用小写字母并用下划线分割(mysql数据库大小写敏感) 例如: 不同的数据库名 DbName dbname 不同的表名 Table table taBLe 2.所有数据库对象名称禁止使用mysql保留关键字 例如 :select id , username , from ,age from table_user 会造成mysql 歧义 3.数据库对象的命名要做到见名识义,并且最好不要超过32个字符 例如:秒杀用户表 miaosha_userdb good!! 用户账号表 user_account good!! 4.所有的临时表必须义tmp为前缀并且已日期为后缀,备份库备份表必须义bak为前缀并且已日期为后缀,大的可以到处sql 5.所有的数据存储的列名和列类型必须一致 custom_inf order_master customer_id int unsigned customer_id int unsigned 必须一致否则会影响性能,一般这种列都是作为表的关联列,如果两个字段的数据类型不同,数据库则会进行隐式的数据类型 转换降低性能,造成列上的索引失效!! 存储规范 1.所有的表必须使用Innodb存储引擎 支持事物行级锁,更好的恢复性,并发性能更好 2.大部分数据库表字符集要统一 (大部分使用UTF-8) 编码乱码 3.所有的表和字段都要添加注释 数据字典的维护 4.尽量控制单表的数据量大小,建议控制在500万以内 当然500万并不是mysql的限制 过大可以通过历史数据归档,分库分表的手段来控制数据量的大小(订单表一类的比较重要) 5.尽量做到冷热数据分离,减少表的宽度 列最大4096列 减少磁盘io,保证热数据的内存缓存命中率,控制列数量也可以更加有效的利用缓存,避免读入无用的冷数据 经常使用的列放在一个表中 6.禁止在表中建立预留字段 预留字段命名很难做到见识义,无法选择合适的类型,对预留字段修改会对表进行锁定 行为规范 1.禁止存储图片,文件等二进制文件,造成大量的io操作 (存在相应的文件服务器上) 2.禁止再线上进行数据库的压力测试 3.禁止从开发环境测试环境直连生产环境 索引设计规范(不要滥用索引) 1.建议单表索引数量不超过5个 索引并不是越多越好过多索引降低效率,优化器过多索引选出最优解 innodb 是按照那个索引的顺序来组织表的呢 主键 不使用更新频繁的列作为主键,不使用多列主键 不使用uuid,md5,hash 字符串列作为主键 不能保证顺序增长 2.那些哪些列上建立索引??? 1.我们经常在select update delete语句的where从句的列建立索引 2.包含在order by , group by , distinct 中的字段 3.多表join的关联列 3.如何选择索引的顺序? 联合索引中 索引从左到右的顺序 建立索引的目的 查询数据的时候可以根据索引来进行数据查找-- 从而减少磁盘的随机io , 增加查询的性能,所以 如果我们的索引能够过滤出更少的数据那么我们从磁盘读入的数据则越少 1.区分度最高的列放在联合索引的最左侧 区分度--数据唯一值的数量/总行数 区分度最大的就应该是主键了 2.尽量字段长度小的列放在联合索引的最左侧 3.使用最频繁的列放在最左侧 4,尽量避免冗余和重复的索引 重复索引了: primary key(id) , index(id) , unique index(id) 冗余: index(a,b,c) , index(a.b) 5.对于频繁使用的查询先优先考虑覆盖索引(包含了所有的查询字段的索引) 6.尽量使用外键 不建议使用外检约束,但是一定要在表与表之间的关联键上建立索引 数据库字段设计规范 1.优先选择符合存储需要的最小的数据类型 1.将字符串转换成数字类型存储 INET_ATON('255.255.255.255') = 4294967295 字符串转ip 将字符串转换成数字类型存储 INET_NTOA('4294967295') = 255.255.255.255 ip 转字符串 2.对于非负数据采用无符号整形进行存储 signed int -2147483648 -- 2147483647 unsigned int -0 -- 4294967295 3.VARCHAR(N)中的N代表的是字符数而不是字节数 使用UTF-8存储汉字varchar(255) = 765个字节 存储255个汉字 4.过大的长度会消耗更多的内存 varchar是一个可变的长度 2.避免使用text,blob数据类型 建议blob或者时text分离到单独的表中 避免使用enum数据类型 3.尽可能的所有列都定义为NOT NULL 索引null列需要额外的空间来保存,所以需要占用更多的空间 进行比较和计算的时候要对null值进行特别的处理 4.字符串存储日期型的数据不是正确的 无法用日期函数来进行计算和比较 用字符串存储日期要占用更多的空间 5.timestamp 和datatime 类型存储时间 timestamp 存储范围有限制 1970-01-01 00:00:01 ~2038-01-19 03:14:07 timestamp占用4字节和INT相同,但是INT可读性能高 6.财务相关的金额类数据,必须由decimal类型存储 decimal类型为精准的浮点数,在计算时不会丢失精度 占用空间由定义的宽度来决定 可用于存储比bigint更大的整数类型 数据库sql开发规范 1.建议使用预编译语句对数据库进行操作 2.避免数据类型的隐式转换 不同表的相同列的数据类型不一致 会导致索引失效 3.重复利用已经存在的索引 1.避免使用双%%的查询条件 如 a like '%1323%' 2.一个sql只能利用到复合索引中的一列进行范围查询 有 a,b,c列的联合索引,在查询条件中有a列的范围查询,则在b,c列上的索引将不会被用到, 在定义联合索引时,如果a列要用到范围查找的话,就要把a列放到联合索引的右侧 3.使用left join 或者not exists 来优化not in(偶尔也会导致索引失效) 操作 4.程序链接不同数据库要使用不同的账号,禁止跨库连接为迁移和分库分表做预备 5.禁止select * 必须使用select <字段列表> (* 无法覆盖索引 减少表结构变更 对程序带来的影响) 6.insert 明确字段列表 7.禁止使用子查询,可以把子查询优化为join操作 子查询结果集无法使用索引 子查询会产生临时表操作,如果子查询数据量大则会更严重 8.避免使用过多的join 关联表 于Mysql来说,是存在关联缓存的,缓存的大小可以由join_buffer_size参数进行设置 在Mysql中,对于同一个SQL多关联(join)一个表,就会多分配一个关联缓存,如果在一个SQL中关联的表越多, 所占用的内存也就越大 如果程序中大量的使用了多表关联的操作,同时join_buffer_size设置的也不合理的情况下,就容易造成服务器内存溢出的情况, 就会影响到服务器数据库性能的稳定性 同时对于关联操作来说,会产生临时表操作,影响查询效率 Mysql最多允许关联61个表,建议不超过5个 9.减少同数据库的交互次数 多个相同的操作合并在一起 10.对应同一列进行or判断时,使用in代替or in 的值不要超过500个 in 操作可以更有效的利用索引,or大多数情况下很少能利用到索引 11.禁止order by rand() 进行随机排序 会把表中所有符合条件的数据装载到内存中,然后在内存中对所有数据根据随机生成的值进行排序 并且可能会对每一行都生成一个随机值,如果满足条件的数据集非常大,就会消耗大量的CPU和IO及内存资源 推荐在程序中获取一个随机值,然后从数据库中获取数据的方式 12.where 从句禁止对列进行函数转换和计算(导致无法使用相关列的索引) SELECT(正确写法) * FROM miaosha_message WHERE create_time >= '20190101' AND create_time < '20190102' SELECT (错误写法) * FROM miaosha_message WHERE date (create_time) = '20190101' 13.不会有重复值时使用UNION ALL 而不是UNION UNION 会把两个结果集的所有数据放到临时表中后再进行去重操作 UNION ALL 不会再对结果集进行去重操作 14.拆分大sql变为小sql 大SQL:逻辑上比较复杂,需要占用大量CPU进行计算的SQL MySQL 一个SQL只能使用一个CPU进行计算 SQL拆分后可以通过并行执行来提高处理效率 数据库操作行为规范 过大数据的(100万)批量写操作要分批多次操作 1.大批量操作可能会导致严重的主从延迟 2. binlog日志为row格式时会产生大量的日志 大批量写操作会产生大量日志,特别是对于row格式二进制数据而言,由于在row格式中会记录每一行数据的修改,我们一次修改的数据越多, 产生的日志量也就会越多,日志的传输和恢复所需要的时间也就越长,这也是造成主从延迟的一个原因 3. 避免产生大事务操作 大批量修改数据,一定是在一个事务中进行的,这就会造成表中大批量数据进行锁定,从而导致大量的阻塞,阻塞会对MySQL的性能产生非常大的影响 特别是长时间的阻塞会占满所有数据库的可用连接,这会使生产环境中的其他应用无法连接到数据库,因此一定要注意大批量写操作要进行分批 4.对于大表的修改使用pt-online-schema-change 1.原理: 会在原表的结构上建造一个新表 复制数据 2.避免延迟,修改时锁表 5.禁止super权限滥用 6.数据账号连接最小 ================================================ FILE: docs/netty.md ================================================ ### Netty 教程 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ####了解NIO和IO | NIO | IO | | :---:| :---:| | 面向缓存区 | 面向流 | | 非阻塞IO | 阻塞IO | | 选择器 |无 | #####面向缓存区和面向流 Java NIO和IO之间的第一差异在于IO是面向流的,其中NIO是面向缓冲的。 面向流的Java IO意味着您一次从流中读取一个或多个字节。你读取的字节取决于你所做的。 他们没有任何缓存空间。此外,你不能向前或向后移动流中的数据。如果您需要在从流中读取的数据中前后移动,则需要首先将其缓存在缓冲区中。 Java NIO的缓存导向方法略有不同。数据先被读入缓存区然后再被处理。您可以根据需要在缓冲区中向前后移动。 这样可以在处理过程中给予您更多的灵活性。但是,您还需要检查缓冲区是否包含所有需要的数据,以便完全处理它。 而且,您需要确保在缓冲区中读取更多数据时,不要覆盖尚未处理的在缓冲区中的数据。 #####非阻塞IO和阻塞IO Java IO的各种流是阻塞的。 这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。 一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。 ######选择器 Java NIO的选择器允许单个线程监视多个通道的输入。您可以使用选择器注册多个通道,然后使用单个线程“选择”具有可用于处理的输入的通道,或选择准备好进行写入的通道。这种选择器机制使单线程更容易管理多个通道。 ####IO编程 我们简化下场景:客户端每隔两秒发送一个带有时间戳的"hello world"给服务端,服务端收到之后打印。 为了方便演示,下面例子中,服务端和客户端各一个类,把这两个类拷贝到你的IDE中,先后运行 IOServer.java 和IOClient.java可看到效果。 下面是传统的IO编程中服务端实现 `````java public class IOServer { public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket(8000); // (1) 接收新连接线程 new Thread(() -> { while (true) { try { // (1) 阻塞方法获取新的连接 Socket socket = serverSocket.accept(); // (2) 每一个新的连接都创建一个线程,负责读取数据 new Thread(() -> { try { byte[] data = new byte[1024]; InputStream inputStream = socket.getInputStream(); while (true) { int len; // (3) 按字节流方式读取数据 while ((len = inputStream.read(data)) != -1) { System.out.println(new String(data, 0, len)); } } } catch (IOException e) { } }).start(); } catch (IOException e) { } } }).start(); } } //server端首先创建了一个serverSocket来监听8000端口。 //然后创建一个线程,线程里面不断调用阻塞方法 serversocket.accept();获取新的连接,见(1),当获取到新的连接之后,给每条连接创建一个新的线程,这个线程负责从该连接中读取数据,见(2),然后读取数据是以字节流的方式,见(3)。 ````` ```java public class IOClient { public static void main(String[] args) { new Thread(() -> { try { Socket socket = new Socket("127.0.0.1", 8000); while (true) { try { socket.getOutputStream().write((new Date() + ": hello world").getBytes()); socket.getOutputStream().flush(); Thread.sleep(2000); } catch (Exception e) { } } } catch (IOException e) { } }).start(); } } //客户端的代码相对简单,连接上服务端8000端口之后,每隔2秒,我们向服务端写一个带有时间戳的 "hello world" ``` 上面的demo,从服务端代码中我们可以看到,在传统的IO模型中,每个连接创建成功之后都需要一个线程来维护,每个线程包含一个while死循环,那么1w个连接对应1w个线程,继而1w个while死循环,这就带来如下几个问题: 线程资源受限:线程是操作系统中非常宝贵的资源,同一时刻有大量的线程处于阻塞状态是非常严重的资源浪费,操作系统耗不起 线程切换效率低下:单机cpu核数固定,线程爆炸之后操作系统频繁进行线程切换,应用性能急剧下降。 除了以上两个问题,IO编程中,我们看到数据读写是以字节流为单位,效率不高。 为了解决这三个问题,JDK在1.4之后提出了NIO ####NIO编程 关于NIO相关的文章网上也有很多,这里不打算详细深入分析,下面简单描述一下NIO是如何解决以上三个问题的。 #####线程资源受限 在NIO模型中,他把这么多while死循环变成一个死循环,这个死循环由一个线程控制,那么他又是如何做到一个线程,一个while死循环就能监测1w个连接是否有数据可读的呢? 这就是NIO模型中selector的作用,一条连接来了之后,现在不创建一个while死循环去监听是否有数据可读了,而是直接把这条连接注册到selector上,然后,通过检查这个selector,就可以批量监测出有数据可读的连接,进而读取数据, #####线程切换效率低下 由于NIO模型中线程数量大大降低,线程切换效率因此也大幅度提高 #####IO读写以字节为单位 NIO解决这个问题的方式是数据读写不再以字节为单位,而是以字节块为单位。IO模型中,每次都是从操作系统底层一个字节一个字节地读取数据,而NIO维护一个缓冲区,每次可以从这个缓冲区里面读取一块的数据, 这就好比一盘美味的豆子放在你面前,你用筷子一个个夹(每次一个),肯定不如要勺子挖着吃(每次一批)效率来得高。 介绍完IO/NIO我们来真正介绍Netty吧 ####了解什么是Netty * Netty的官方解释 Netty是由JBOSS提供的一个java开源框架。 Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 * Netty的简单概括 Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架。 ####Netty的特性呢 >1.统一的API,支持多种传输类型,阻塞的和非阻塞的简单而强大的线程模型真正的无连接数据报套接字支持链接逻辑组件以支持复用。 >2.拥有比Java的核心API更高的吞吐量以及更低的延迟得益于池化和复用,拥有更低的资源消耗最少的内存复制。 >3.不会因为慢速、快速或者超载的连接而导致OutOfMemoryError消除在高速网络中NIO应用程序常见的不公平读/写比率。 >4.完整的SSL/TLS以及StartTLS支持可用于受限环境下,如Applet和OSGI。 >等等。 好 让我们动手写一个Netty客户端和服务端吧 ####Netty客户端 ```java package com.example.netty.http; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.*; import io.netty.util.AsciiString; public class HttpHandler extends SimpleChannelInboundHandler { private AsciiString contentType = HttpHeaderValues.TEXT_PLAIN; @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception { System.out.println("class:" + msg.getClass().getName()); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer("test".getBytes())); HttpHeaders heads = response.headers(); heads.add(HttpHeaderNames.CONTENT_TYPE, contentType + "; charset=UTF-8"); heads.add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); // 3 heads.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); ctx.write(response); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { System.out.println("channelReadComplete"); super.channelReadComplete(ctx); ctx.flush(); // 4 } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("exceptionCaught"); if (null != cause) cause.printStackTrace(); if (null != ctx) ctx.close(); } } ``` ####Netty服务端 ```java package com.example.netty.http; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.sctp.nio.NioSctpServerChannel; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; public class HttpServer { private final int port ; public HttpServer(int port) { this.port = port; } public void start(){ ServerBootstrap bootStrap = new ServerBootstrap(); NioEventLoopGroup group = new NioEventLoopGroup(); bootStrap.group(group).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { System.out.println("channel :" +ch); ch.pipeline().addLast("decoder", new HttpRequestDecoder()) .addLast("encoder", new HttpResponseEncoder()) // 2 .addLast("aggregator", new HttpObjectAggregator(512 * 1024)) // 3 .addLast("handler", new HttpHandler()); } }); } public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println( "Usage: " + HttpServer.class.getSimpleName() + " "); return; } int port = Integer.parseInt(args[0]); new HttpServer(port).start(); } } //To be continued! ``` ####参考文档 [Netty是什么?](https://www.jianshu.com/p/a4e03835921a) To be continued!!!! To be continued!!!! ================================================ FILE: docs/ngnix-good.md ================================================ ### 秒杀nginx优化 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ##要求: >目标 1.并发优化 2.KeepALive长连接优化 3.压缩优化 4.配置缓存 #### [/docs/tools/nginx nginx优化相关包](/docs/tools) 安装:cd yum install -y gcc gcc-c++ ./configure --prefix=/usr/local/nginx --with-pcre=/home/qiurunze/下载/pcre-8.38 --with-http_stub_status_module --with-http_gzip_static_module --add-module=/home/qiurunze/下载/ngx_cache_purge-2.3 make make install ps -ef | grep nginx ./sbin/nginx -s reload http://nginx.org/en/docs/ 1.工作线程数和并发连接数 worker_processes 4; #cpu,如果nginx单独在一台机器上 worker_processes auto; events { worker_connections 4096;#每一个进程打开的最大连接数,超出了log中会有记录 multi_accept on; #可以一次建立多个连接 use epoll; } worker_rlimit_nofile 10240;每个进程打开的最大的文件数,受限于操作系统: vi /etc/security/limits.conf * hard nofile 102400 * soft nofile 102400 * soft core unlimited * soft stack 10240 2.操作系统优化 配置文件/etc/sysctl.conf sysctl -w net.ipv4.tcp_syncookies=1#防止一个套接字在有过多试图连接到达时引起过载 sysctl-w net.core.somaxconn=1024#默认128,连接队列 sysctl-w net.ipv4.tcp_fin_timeout=10 # timewait的超时时间 sysctl -w net.ipv4.tcp_tw_reuse=1 #os直接使用timewait的连接 sysctl -w net.ipv4.tcp_tw_recycle = 0 #回收禁用 3.Keepalive长连接 Nginx与upstream server: upstream server_pool{ server localhost:8080 weight=1 max_fails=2 fail_timeout=30s; keepalive 300; #300个长连接 } 同时要在location中设置: location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } 客户端与nginx(默认是打开的): 4.keepalive_timeout 60s; #长连接的超时时间 keepalive_requests 100; #100个请求之后就关闭连接,可以调大 keepalive_disable msie6; #ie6禁用启用压缩 gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_proxied any; gzip_types text/html text/plain application/x-javascript application/javascript text/css application/xml gzip_vary on; #Vary: Accept-Encoding gzip_static on; #如果有压缩好的 直接使用 5.状态监控 location = /nginx_status { stub_status on; access_log off; allow ; deny all; } 输出结果: Active connections: 1 server accepts handled requests 17122 17122 34873 Reading: 0 Writing: 1 Waiting: 0 Active connections:当前实时的并发连接数 accepts:收到的总连接数, handled:处理的总连接数 requests:处理的总请求数 Reading:当前有都少个读,读取客户端的请求 Writing:当前有多少个写,向客户端输出 Waiting:当前有多少个长连接(reading + writing) reading – nginx reads request header writing – nginx reads request body, processes request, or writes response to a client waiting – keep-alive connections, actually it is active - (reading + writing) 6.实时请求信息统计ngxtop https://github.com/lebinh/ngxtop (1)安装python-pip yum install epel-release yum install python-pip (2)安装ngxtop pip install ngxtop (3)使用 指定配置文件: ngxtop -c ./conf/nginx.conf 查询状态是200: ngxtop -c ./conf/nginx.conf --filter 'status == 200' 查询那个ip访问最多: ngxtop -c ./conf/nginx.conf --group-by remote_addr ----------------------------------------------------------------------------- nginx.conf配置文件 user www; worker_processes 4;#取决于cpu error_log logs/error.log; pid logs/nginx.pid; worker_rlimit_nofile 10240; #每个进程打开的最大的文件数,受限于操作系统/etc/security/limits.conf events { worker_connections 10240;#每一个进程打开的最大连接数,超出了log中会有记录 multi_accept on; #可以一次建立多个连接 use epoll; } http { include mime.types; default_type application/octet-stream; server_tokens off; #隐藏版本号 client_max_body_size 10m; #文件上传需要调大 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; #默认写日志:打开文件写入关闭,max:缓存的文件描述符数量,inactive缓存时间,valid:检查时间间隔,min_uses:在inactive时间段内使用了多少次加入缓存 open_log_file_cache max=200 inactive=20s valid=1m min_uses=2; sendfile on; tcp_nopush on; #与浏览器的长连接 keepalive_timeout 65;#长连接超时时间 keepalive_requests 500;#500个请求以后,关闭长连接 keepalive_disable msie6; # 启用压缩 gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_proxied any; gzip_types text/plain application/x-javascript application/javascript text/css application/xml; gzip_vary on; #Vary: Accept-Encoding gzip_static on; #如果有压缩好的 直接使用 #超时时间 proxy_connect_timeout 5; #连接proxy超时 proxy_send_timeout 5; # proxy连接nginx超时 proxy_read_timeout 60;# proxy响应超时 # 开启缓存,2级目录 proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=20g; proxy_ignore_headers X-Accel-Expires Expires Cache-Control; proxy_hide_header Cache-Control; proxy_hide_header Pragma; #反向代理服务器集群 upstream server_pool{ server localhost:8080 weight=1 max_fails=2 fail_timeout=30s; server localhost:8081 weight=1 max_fails=2 fail_timeout=30s; keepalive 200; # 最大的空闲的长连接数 } server { listen 80; server_name localhost 192.168.220.133; location / { #长连接 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; #Tomcat获取真实用户ip proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://server_pool; } # 状态监控 location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; allow 192.168.220.133; deny all; } #用于清除缓存 location ~ /purge(/.*) { allow 127.0.0.1; allow 192.168.220.133; deny all; proxy_cache_purge cache_one $host$1$is_args$args; } # 静态文件加缓存 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css|html|htm)?$ { expires 1d; proxy_cache cache_one; proxy_cache_valid 200 304 1d; proxy_cache_valid any 1m; proxy_cache_key $host$uri$is_args$args; proxy_pass http://server_pool; } } } ================================================ FILE: docs/old.md ================================================ ![互联网 Java 秒杀系统设计与架构](https://raw.githubusercontent.com/qiurunze123/imageall/master/miaoshashejitu.png) > 邮箱 : [QiuRunZe_key@163.com](QiuRunZe_key@163.com) > Github : [https://github.com/qiurunze123](https://github.com/qiurunze123) > QQ : [3341386488](3341386488) > QQ群(秒杀架构一群) : 950056961 > QQ群(秒杀架构二群) : 652032632 > QQ群3(多线程交流群 三高系统 -- 并发框架) :453259026 [![Travis](https://img.shields.io/badge/language-Java-yellow.svg)](https://github.com/qiurunze123) 高并发大流量如何进行秒杀架构,我对这部分知识做了一个系统的整理,写了一套系统。本GitHub还有许多其他的知识,随时欢迎探讨与骚扰!本文还在更新如果文章出现瑕疵请及时与我联系! 文章还有许多不足,我仍在不断改进!如果你本地没有这些环境,可以先找我要我的阿里云地址,看效果! ps: 本文章基础思路来自于若鱼1919老师!大家可以关注老师的课和博客很不错,老师很nice! 谢谢大家 !课程地址:https://coding.imooc.com/class/168.html 一点小建议:学习本系列知识之前,如果你完全没接触过 `MQ`、`SpringBoot`、`Redis`、`Dubbo`、`ZK` 、`Maven`,`lua`等,那么我建议你可以先在网上搜一下每一块知识的快速入门, 也可以下载本项目边做边学习,我的项目完全是实战加讲解不想写一堆的文章,浪费我们的生命,你还不懂内层含义,想要明白就边实际操作边学习,效果会更好!加油💪💪 新版正在更新,旧版入口: - [首页](README.md) ### 最初版本请下载 (https://pan.baidu.com/s/1sld8RBSvLe2q4gc-Z-fVAQ) ### 如果想先看dubbo + zk 了解请下载we-miaosha ,miaosha-order 为项目分离示例项目!会不断完善!此版本为springboot2.0+ 请使JDK1.8+ ### start 维护 开始搭建 > 软件环境 : 请选择稳定版 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/miaosha.png) > 未来设计图 : 未来设计 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/miaoshafuture.png) > 软件环境 : mysql 数据库表设计 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/miaoshasql.png) >1.需注意 因为秒杀,大促,打折等活动进行频繁,所以需要单独建立秒杀_....表来管理否则会经常进行回归 >2.本sql只是进行模拟,现实情况比这个信息要复杂的多,你可以把它看作是一个简化版本的sql >3.访问地址 http://localhost:8080/login/to_login ### 以下所有内容都已完成,但是因内容多需逐渐整理上传! 专题的部分也会尽快上传更新! 立个flag 半年内吧争取全部更新完!各位稍安勿躁! ### [如要提交代码请先看--提交合并代码规范提交者的后面都会有署名方便大家问问题](/docs/code-criterion.md) | ID | Problem | Article | | --- | --- | :--- | | 000 |如何解决卖超问题 | [解决思路](/docs/code-solve.md) | | 001 |如何对本项目进行jmeter压测 | [解决思路](/docs/jemter-solve.md) | | 003 |全局异常处理拦截 |[解决思路](/docs/code-solve.md) | | 003 |页面级缓存thymeleafViewResolver |[解决思路](/docs/code-solve.md) | | 004 |对象级缓存redis🙋🐓 |[解决思路](/docs/code-solve.md) | | 005 |订单处理队列rabbitmq |[解决思路](/docs/code-solve.md) | | 006 |解决分布式session |[解决思路](/docs/code-solve.md) | | 007 |秒杀安全 -- 安全性设计 |[解决思路](/docs/code-solve.md) | | 008 |通用缓存key的封装采用什么设计模式 |[解决思路](/docs/code-solve.md) | | 009 |redis的库存如何与数据库的库存保持一致 |[解决思路](/docs/code-solve.md) | | 010 |为什么redis数量会减少为负数 |[解决思路](/docs/code-solve.md) | | 011 |为什么要单独维护一个秒杀结束标志 |[解决思路](/docs/code-solve.md) | | 012 |rabbitmq如何做到消息不重复不丢失即使服务器重启 |[解决思路](/docs/code-solve.md) | | 013 |为什么threadlocal存储user对象,原理 |[解决思路](/docs/code-solve.md) | | 014 |maven 隔离 |[解决思路](/docs/code-solve.md) | | 015 |服务降级--服务熔断(过载保护)(未更新)) |[解决思路](/docs/code-solve.md) | | 016 |redis 分布式锁实现方法 |[解决思路](/docs/code-solve.md) | | 017 |定时关单模拟与分布式锁(未更新文章--代码已更新) |[解决思路](/docs/time-close.md) | | 018 |tomcat配置和优化 |[解决思路]((/docs/tomcat-good.md)) | | 018 |tomcat集群配置 |[解决思路](/docs/tomcat-group.md) | | 020 |Nginx优化(前端缓存) |[解决思路](/docs/ngnix-good.md) | | 021 |重点 *** RPC分布式补偿如何解决(已更新 两种写法) |[解决思路](/docs/code-rpc.md) | | 022 |分布式事物解决方案(已更新 -- 最新的思路和写法) |[解决思路](/docs/code-rpc.md) | | 023 |mysql主从复制思路及实操(未更新代码) |[解决思路](/docs/mysql-master-slave.md) | | 024 |如何进行分库分表 |[解决思路](/docs/mysql-master-slave.md) | | 025 |秒杀类似场景sql的写法注意事项有哪些?|[解决思路](/docs/mysql-master-slave.md) | | 026 |如何利用lua脚本进行操作限流与分布式锁(可保证原子性)?|[解决思路](/docs/redis-good.md) | | 027 |如何利用lua脚本进行分布式锁操作?|[解决思路](/docs/redis-good.md) | | 028 |网站访问统计实现?|[解决思路](/docs/code-solve.md) | | 028 |项目进行dubbo + zk 改造 (已完成dubbo嵌入--springboot 与dubbo结合xml版本)?|[解决思路](/docs/code-solve.md) | | 029 |dubbo客户端 dubbo-admin管理平台 搭建安装|[解决思路](/docs/dubbo-admin.md) | | 030 |如何利用dubbo 的mock 来进行服务降级本地伪装 ?? (有更好的方式进群@我)|[解决思路](/docs/dubbo-zk.md) | | 031 |*** 如何利用lua + redis 取代 nigix + lua 脚本进行分布式限流 (请看miaosha-2version) ? *** |[解决思路](/docs/redis-good.md) | | 032 |多数据源配置 如何进行多数据源配置 |[解决思路](/docs/code-solve.md) | #### [分布式系统发展历程(已更新)](/docs/fenbushi.md) #### [生产环境内存调优](/docs/jvm-goods.md) #### [mybatis源码解析与使用--未更新](/docs/mybatis-code.md) #### [redis 使用与进阶以及如何进行集群--已更新](/docs/redis-good.md) #### [spring源码--未更新](/docs/redis-code.md) #### [分布式治理框架-dubbo - zk - 解析--更新中](/docs/dubbo-zk.md) #### [多线程分析以及三高多线程demo系统 ](https://github.com/qiurunze123/threadandjuc) #### [微服务框架--未更新](/docs/redis-code.md) -------------------------------------------------| #### [mysql数据库优化及架构学习](/docs/mysql.md) ##### [mysql数据库设计规范(已更新)](/docs/mysql.md) ##### [mysql数据库设计实例(已更新)](/docs/mysql-1.md) ##### [mysql数据库执行计划分析(已更新)](/docs/mysql-2.md) ##### [mysql数据库备份和恢复(已更新)](/docs/mysql-3.md) ##### [mysql数据库架构变迁(已更新)](/docs/mysql-3.md) --------------------------------------------------| #### [netty专题(已更新 by liuxiangyu)](/docs/netty.md) #### [linux专题](/docs/linux.md) #### [面试专题(最后更新)--未更新](/docs/code-solve.md) ###### [maven-wrapper介绍(add by zhangkai)](/docs/maven-wrapper.md) ================================================ FILE: docs/redis-good.md ================================================ ### redis 使用与进阶 有问题或者宝贵意见联系我的QQ,非常希望你的加入! >目标 (希望大家仔细研究redis.conf配置文件-本文很多基础的一带而过) 1.redis分布式锁,zk分布式锁,lua脚本限流,lua分布式锁 2.redis持久化策略 3.redis集群 4.redis的简单操练 整理大部分常用的场景与使用,如果有疑问或者你不懂的地方请联系我! #### 1 redis分布式锁 >1.分布式系统(单机的使用ReentrantLock或者synchronized代码块来实现) >2.共享资源大并发产生 >3.同步访问 **redis分布式锁解决什么问题** 1.一个进程中的多个线程,多个线程并发访问同一个资源的时候,如何解决线程安全问题。 2.一个分布式架构系统中的两个模块同时去访问一个文件对文件进行读写操作 3.多个应用对同一条数据做修改的时候,如何保证数据的安全性 但在一个进程中,我们可以用到synchronized、lock之类的同步操作去解决,但是对于分布式架构下多进程的情况下, 如何做到跨进程的锁。就需要借助一些第三方手段来完成 **设计一个分布式所需要解决的问题,分布式锁解决方案(数据库方案)** 数据库解决方式,创建一个表叫做LOCK表 lock( id int(11) methodName varchar(100),--锁定的方法名称 memo varchar(1000) modifyTime timestamp unique key mn (method) --唯一约束 ) 在执行方法的时候,获取锁的伪代码 或者for update行锁 或者 乐观锁方式也是可以的 try{ exec insert into lock(methodName,memo) values(‘method’,’desc’); return true; }Catch(DuplicateException e){ return false; } 释放锁: delete from lock where methodName=’’; **(数据库方案)存在的问题以及思考** 1.锁没有失效时间,一旦解锁操作失败,就会导致锁记录一直在数据库中,其他线程无法再获得到锁 2.锁是非阻塞的,数据的insert操作,一旦插入失败就会直接报错。没有获得锁的线程并不会进入排队队列 要想再次获得锁就要再次触发获得锁操作 3.锁是非重入的,同一个线程在没有释放锁之前无法再次获得该锁(要解决这个问题可以在表中多加一列用于记录线程名称,通过判断这个列来实现重入) **ZK方案** ZK方案实现之前你要先了解ZK关于他的节点的几个特性: 有序节点:假如当前有一个父节点为/lock,我们可以在这个父节点下面创建子节点;zookeeper提供了一个可选的有序特性 例如我们可以创建子节点“/lock/node-”并且指明有序,那么zookeeper在生成子节点时会根据当前的子节点数量自动添加整数序号 也就是说如果是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一个节点则为/lock/node-0000000001,依次类推 临时节点:客户端可以建立一个临时节点,在会话结束或者会话超时后,zookeeper会自动删除该节点 事件监听:在读取数据时,我们可以同时对节点设置事件监听,当节点数据或结构变化时,zookeeper会通知客户端 当前zookeeper有如下四种事件: 1)节点创建 2)节点删除 3)节点数据修改 4)子节点变更 获取分布式锁的流程 ------- 假设所空间的根节点为/lock 1.客户端连接zookeeper,并在/lock下创建临时的且有序的子节点 第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推 2.--避免羊群效应--客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点, 如果是则认为获得锁,否则监听刚好在自己之前一位的子节点删除消息,获得子节点变更通知后重复此步骤直至获得锁 3.实行业务代码 4.流程完成后,删除对应的子节点并释放锁 (Watch机制) 对应分布式开源包Curator ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/zk.png) **Redis分布式锁方案** Redis 中有许多的命令都可以实现分布式锁,但是比较常用的是SETNX这个命令来实现 有多种方案代码: 1.获取锁,释放锁 代码在redismanager 里面 (简单版) ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/redislock1.png) ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/redislock2.png) closeOrder也有 不过是另一种!比较复杂!! 加入时间对比如果当前时间已经大与释放锁的时间 说明已经可以释放这个锁重新在获取锁,setget方法可以把之前的锁去掉在重新获取,旧值在于之前的 值比较,如果无变化说明这个期间没有人获取或者操作这个redis锁,则可以重新获取 ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/redislock3.png) redis有成熟的框架redission **Redis多路复用机制(看不看都行)** linux的内核会把所有外部设备都看作一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令, 返回一个 file descriptor(文件描述符)。对于一个socket的读写也会有响应的描述符,称为socketfd(socket 描述符)。 而IO多路复用是指内核一旦发现进程指定的一个或者多个文件描述符IO条件准备好以后就通知该进程 IO多路复用又称为事件驱动,操作系统提供了一个功能,当某个socket可读或者可写的时候,它会给一个通知。 当配合非阻塞socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据。 操作系统的功能通过select/pool/epoll/kqueue之类的系统调用函数来使用,这些函数可以同时监视多个描述符的读写就绪情况 ,这样多个描述符的I/O操作都能在一个线程内并发交替完成,这就叫I/O多路复用,这里的复用指的是同一个线程 多路复用的优势在于用户可以在一个线程内同时处理多个socket的 io请求。达到同一个线程同时处理多个IO请求的目的。 而在同步阻塞模型中,必须通过多线程的方式才能达到目的 **Redis(2.6以后)--lua脚本** 1.减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行 2.原子操作,redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。换句话说,编写脚本的过程中无需担心会出现竞态条件 3.复用性,客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑 4.脚本可以通过return 来返回客户端 例子: 利用lua脚本进行电话号或则IP限流 实例 具体请看 redislua类 KEYS[1] ARGV[1] ARGV[2] key 参数1 参数2 local num=redis.call('incr',KEYS[1]) if tonumber(num)==1 then redis.call('expire',KEYS[1],ARGV[1]) return 1 elseif tonumber(num)>tonumber(ARGV[2]) then return 0 else return 1 end **Redis(2.6以后)--lua--EVALSHA命令** 考虑到我们通过eval执行lua脚本,脚本比较长的情况下,每次调用脚本都需要把整个脚本传给redis 比较占用带宽。为了解决这个问题,redis提供了EVALSHA命令允许开发者通过脚本内容的SHA1摘要来执行脚本。该命令的用法和EVAL一样, 只不过是将脚本内容替换成脚本内容的SHA1摘要 1. Redis在执行EVAL命令时会计算脚本的SHA1摘要并记录在脚本缓存中 2. 执行EVALSHA命令时Redis会根据提供的摘要从脚本缓存中查找对应的脚本内容 如果找到了就执行脚本,否则返回“NOSCRIPT No matching script,Please use EVAL” 演示流程: ```shell # 计算出脚本的sha1,用于后续验证 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'" "232fd51614574cf0867b83d384a5e898cfd24e5a" # 判断脚本存在 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a 1) (integer) 1 # 清空所有脚本 127.0.0.1:6379> SCRIPT FLUSH OK # 判断脚本不存在 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a 1) (integer) 0 # 直接运行脚本,redis会自动进行缓存 127.0.0.1:6379> EVAL "return 'hello moto'" 0 "hello moto" # 根据缓存中的sha1来直接运行脚本 127.0.0.1:6379> EVALSHA 232fd51614574cf0867b83d384a5e898cfd24e5a 0 "hello moto" ``` **Redis(2.6以后)--lua脚本运行限制** redis的脚本执行是原子的,即脚本执行期间Redis不会执行其他命令 所有的命令必须等待脚本执行完以后才能执行。为了防止某个脚本执行时间过程导致Redis无法提供服务 Redis提供了lua-time-limit参数限制脚本的最长运行时间--默认是5秒钟 当脚本运行时间超过这个限制后,Redis将开始接受其他命令但不会执行(以确保脚本的原子性),而是返回BUSY的错误 在第一个窗口中执行lua脚本的死循环 eval “while true do end” 0 在第二个窗口中运行get hello 最后第二个窗口的运行结果是Busy, 可以通过script kill命令终止正在执行的脚本 如果当前执行的lua脚本对redis的数据进行了修改,比如(set)操作,那么script kill命令没办法终止脚本的运行, 因为要保证lua脚本的原子性。如果执行一部分终止了,就违背了这一个原则 在这种情况下,只能通过 shutdown nosave命令强行终止 **Redis(2.6以后)--lua分布式锁** ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/lualock.png) **如何利用lua + redis 取代 nigix + lua 脚本进行分布式限流** 分布式限流的关键就是把限流做成具有原子性的功能,可以使用redis + lua 来进行技术实现,高并发和高性能,实现时间窗口内的流量控制 操作在lua脚本中又因为redis是单线程的,因此线程安全!Redis 将整个脚本作为一个原子执行, 无需担心并发, 也就无需事务; ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/lualimit1.png) ![整体流程](https://raw.githubusercontent.com/qiurunze123/imageall/master/lualimit2.png) lua脚本一致存在于redis 中可以 限制每秒钟的请求数实现限流! 这里提供一种基于zset的信号量实现方式: - zset的成员为uuid,唯一代表某一个线程,分数是当前的时间戳 - 限制zset中给的成员数量来实现限流 - 根据zset的分值(时间戳)按大小进行排序,移除某一范围的成员,实现超时移除处理 假定zset的名字为`xhlZset`,获取信号量: ``` // 被动触发超时处理:将已经超时的信号量移除出zset zremrangebyscore xhlZset -inf now-timeout // 如果信号量的数量没有超出限制 if zcard xhlZset < limit { // 添加,记录uuid以及当前时间戳now zadd xhlZset now uuid return 1 } return 0 ``` 释放信号量 ``` zrem xhlZset uuid ``` ================================================ FILE: docs/redis-lua.md ================================================ ### lua学习 有问题或者宝贵意见联系我的QQ,非常希望你的加入! >数据类型 ================================================ FILE: docs/tomcat-good.md ================================================ xiu修改### 秒杀tomcat优化 有问题或者宝贵意见联系我的QQ,非常希望你的加入! ##要求: > 本文以tomcat8.5.20为准 >目标 1.内存优化 2.并发优化 3.APR优化 #### [APR优化相关包](/docs/tools) 1.**内存优化** 内存优化catalina JAVA_OPTS="-server -Xms2048M -Xmx2048M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$CATALINA_HOME/logs/heap.dump" # Register custom URL handlers server.xml 配置 maxConnections="300" acceptCount="200" maxThreads="400" minSpareThreads="200"/> 禁用 ${tomcat}/webapps/docs/config/host.html autoDeploy:This flag value indicates if Tomcat should check periodically for new or updated web applications while Tomcat is running ${tomcat}/webapps/docs/config/http.html enableLookups:false ${tomcat}/webapps/docs/config/context.html: reloadable:false 2.**如果你的网站具有高并发那么建议使用APR模式** http://apr.apache.org/ 依赖: >>APR 1.2+ development headers (libapr1-dev package) >>OpenSSL 1.0.2+ development headers (libssl-dev package) >>JNI headers from Java compatible JDK 1.4+ >>GNU development environment (gcc, make) yum install apr* openssl-devel gcc make tar zxvf apr-1.4.5.tar cd apr-1.4.5 ./configure --prefix=/usr/local/apr make make install tar -zxvf apr-iconv-1.2.1.tar.gz cd apr-iconv-1.2.1 ./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr make make install yum install expat-devel tar zxvf apr-util-1.3.12.tar.gz cd apr-util-1.3.12 ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr make make install 安装openssl 1.0.2 ./config --prefix=/usr/local/openssl 修改Makefile: vi Makefile 将原来的:CFLAG= -DOPENSSL_THREADS 修改为: CFLAG= -fPIC -DOPENSSL_THREADS 也就是添加-fPIC 执行执行: make && make install cd bin tar -zxvf tomcat-native.tar.gz cd tomcat-native-1.2.12-src cd native ./configure --with-apr=/usr/local/apr --with-ssl=/usr/local/openssl make make install catalina.sh: JAVA_OPTS="$JAVA_OPTS -Djava.library.path=/usr/local/apr/lib 注意:开启了apr之后,jvm用到的native内存会增大,因此要适当调大Metaspace空间,添加JVM选项:-XX:MetaspaceSize=128m JAVA_OPTS="-server -Xms2048M -Xmx2048M -XX:MetaspaceSize=128M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$CATALINA_HOME/logs/heap.dump" server.xml: ================================================ FILE: miaosha-admin/.gitignore ================================================ /.settings/ /.project ================================================ FILE: miaosha-admin/miaosha-admin-api/pom.xml ================================================ 4.0.0 com.geekq miaosha-admin ${revision} miaosha-admin-api org.projectlombok lombok provided com.geekq miaosha-admin-common org.mybatis mybatis-spring org.mybatis mybatis ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/entity/Account.java ================================================ package com.geekq.admin.entity; import com.geekq.common.utils.md5.MD5Utils; import com.geekq.common.utils.numcal.BidConst; import lombok.Getter; import lombok.Setter; import org.apache.ibatis.type.Alias; import java.math.BigDecimal; /** * 用户的帐户信息账户 一个LoginInfo 对应一个UserInfo对应一个Account * * @author 邱润泽 */ @Getter @Setter @Alias("Account") public class Account extends BaseDomain { private static final long serialVersionUID = 6760287512112252557L; private int version; private String tradePassword; // 交易密码 private BigDecimal usableAmount = BidConst.ZERO; // 可用余额 private BigDecimal freezedAmount = BidConst.ZERO; // 冻结金额 private BigDecimal unReceiveInterest = BidConst.ZERO; // 账户待收利息 private BigDecimal unReceivePrincipal = BidConst.ZERO; // 账户待收本金 private BigDecimal unReturnAmount = BidConst.ZERO; // 账户待还金额 private BigDecimal remainBorrowLimit = BidConst.ZERO; // 账户剩余授信额度 private BigDecimal borrowLimitAmount; // 授信额度(当前还可以信用借款额度) private String abstractInfo;//摘要信息用于防篡改检查; public static Account empty(Long id) { Account account = new Account(); account.setId(id); account.setBorrowLimitAmount(BidConst.DEFALUT_BORROWLIMITAMOUNT); account.setRemainBorrowLimit(BidConst.DEFALUT_BORROWLIMITAMOUNT); return account; } public String getAbstractInfo() {//可用余额 + 冻结金额 + 账户神域的授权额度 return MD5Utils.MD5(usableAmount.add(freezedAmount) .add(remainBorrowLimit).toString()); } public boolean checkAbstractInfo() {//可用余额 + 冻结金额 + 账户神域的授权额度 return MD5Utils.MD5( usableAmount.add(freezedAmount).add(remainBorrowLimit) .toString()).equals(abstractInfo); } public BigDecimal getTotalAmount() { return usableAmount.add(freezedAmount).add(unReceivePrincipal); } public void addUseableAmount(BigDecimal amount) { this.usableAmount = this.usableAmount.add(amount); } public void addFreezedAmount(BigDecimal amount) { this.freezedAmount = this.freezedAmount.add(amount); } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/entity/BaseDomain.java ================================================ package com.geekq.admin.entity; import lombok.Getter; import lombok.Setter; import java.io.Serializable; /** * @author qiurunze */ @Getter @Setter public class BaseDomain implements Serializable { protected Long id; } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/entity/IpLog.java ================================================ package com.geekq.admin.entity; import lombok.Getter; import lombok.Setter; import org.apache.ibatis.type.Alias; import java.util.Date; /** * 登陆日志 * * @author Administrator */ @Getter @Setter @Alias("IpLog") public class IpLog extends BaseDomain { public static int LOGINSTATE_FAILD = 0;//登陆失败 public static int LOGINSTATE_SUCCESS = 1;//登陆成功 private String username; private Date loginTime; private String ip; private int loginState; private int loginType; private Long loginInfoId; public IpLog() { super(); } public IpLog(String username, Date loginTime, String ip, int loginType, Long loginInfoId) { super(); this.username = username; this.loginTime = loginTime; this.ip = ip; this.loginState = IpLog.LOGINSTATE_FAILD; this.loginType = loginType; this.loginInfoId = loginInfoId; } public String getDisplayState() { return this.loginState == LOGINSTATE_FAILD ? "登录失败" : "登录成功"; } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/entity/Logininfo.java ================================================ package com.geekq.admin.entity; import com.geekq.common.enums.Constants; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.io.Serializable; import java.util.Date; @Setter @Getter @AllArgsConstructor @NoArgsConstructor public class Logininfo implements Serializable { private Long id; private String nickname; private String password; private String salt; private Date registerDate; private Date lastLoginDate; private int state = Constants.STATE_NORMAL; private int userType;//用户类型 private boolean admin = false; } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/entity/SystemDictionary.java ================================================ package com.geekq.admin.entity; import com.alibaba.fastjson.JSONObject; import lombok.Getter; import lombok.Setter; import org.apache.ibatis.type.Alias; import java.util.HashMap; import java.util.Map; /** * 数据字典 * * @author Stef */ @Getter @Setter @Alias("SystemDictionary") public class SystemDictionary extends BaseDomain { private static final long serialVersionUID = 3382007784095246946L; private String sn; // 编码 private String title; // 名称 private String intro; // 简介 public String getJsonString() { Map m = new HashMap<>(); m.put("id", getId()); m.put("sn", sn); m.put("title", title); m.put("intro", intro); return JSONObject.toJSONString(m); } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/entity/SystemDictionaryItem.java ================================================ package com.geekq.admin.entity; import com.alibaba.fastjson.JSONObject; import lombok.Getter; import lombok.Setter; import org.apache.ibatis.type.Alias; import java.util.HashMap; import java.util.Map; /** * 数据字典明细 * * @author Stef */ @Getter @Setter @Alias("SystemDictionaryItem") public class SystemDictionaryItem extends BaseDomain { private static final long serialVersionUID = 4520006109163647891L; private Long parentId; // 系统目录 private String title; // 名称 private String tvalue; // 值 private Integer sequence; // 序列 private String intro; // 说明 public String getJsonString() { Map m = new HashMap<>(); m.put("id", getId()); m.put("parentId", parentId); m.put("title", title); m.put("tvalue", tvalue); m.put("sequence", sequence); m.put("intro", intro); return JSONObject.toJSONString(m); } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/entity/Userinfo.java ================================================ package com.geekq.admin.entity; import com.geekq.common.utils.numcal.BitStatesUtils; import lombok.Getter; import lombok.Setter; import org.apache.ibatis.type.Alias; import org.springframework.util.StringUtils; /** * @author 邱润泽 */ @Getter @Setter @Alias("UserInfo") public class Userinfo extends BaseDomain { private static final long serialVersionUID = -2194938919842714855L; /** * 版本号 */ private int version; /** * 位状态 */ private Long bitState = 0L; /** * 对应实名认证中的真实姓名 */ private String realName; /** * 对应实名认证中的身份证号 */ private String idNumber; /** * 用户邮箱 */ private String email; /** * 手机号 */ private String phoneNumber = ""; /** * 用户当前认证分数 */ private int authScore = 0; /** * 用户有效的实名认证对象 */ private Long realauthId; /** * 会员的基本资料 * 月收入 */ private SystemDictionaryItem incomeGrade; /** * 婚姻情况 */ private SystemDictionaryItem marriage; /** * 子女情况 */ private SystemDictionaryItem kidCount; /** * 学历 */ private SystemDictionaryItem educationBackground; /** * 住房条件 */ private SystemDictionaryItem houseCondition; public static Userinfo empty(Long id) { Userinfo userinfo = new Userinfo(); userinfo.setId(id); userinfo.setBitState(BitStatesUtils.OP_BASIC_INFO); return userinfo; } /** * 获取用户真实名字的隐藏字符串,只显示姓氏 * * @param realName 真实名字 * @return */ public static String getAnonymousRealName(String realName) { if (StringUtils.hasLength(realName)) { int len = realName.length(); String replace = ""; replace += realName.charAt(0); for (int i = 1; i < len; i++) { replace += "*"; } return replace; } return realName; } /** * 获取用户身份号码的隐藏字符串 * * @param idNumber * @return */ public static String getAnonymousIdNumber(String idNumber) { if (StringUtils.hasLength(idNumber)) { int len = idNumber.length(); String replace = ""; for (int i = 0; i < len; i++) { if ((i > 5 && i < 10) || (i > len - 5)) { replace += "*"; } else { replace += idNumber.charAt(i); } } return replace; } return idNumber; } /** * 获取用户手机号码的隐藏字符串 * * @param phoneNumber 用户手机号码 * @return */ public static String getAnonymousPhoneNumber(String phoneNumber) { if (StringUtils.hasLength(phoneNumber)) { int len = phoneNumber.length(); String replace = ""; for (int i = 0; i < len; i++) { if (i > 2 && i < 7) { replace += "*"; } else { replace += phoneNumber.charAt(i); } } return replace; } return phoneNumber; } /** * 获取用户住址的隐藏字符串 * * @param currentAddress 用户住址 * @return */ public static String getAnonymousCurrentAddress(String currentAddress) { if (StringUtils.hasLength(currentAddress) && currentAddress.length() > 4) { String last = currentAddress.substring(currentAddress.length() - 4, currentAddress.length()); String stars = ""; for (int i = 0; i < currentAddress.length() - 4; i++) { stars += "*"; } return stars + last; } return currentAddress; } public void addState(Long state) { this.bitState = BitStatesUtils.addState(this.bitState, state); } public void removeState(Long state) { this.bitState = BitStatesUtils.removeState(this.bitState, state); } public boolean getIsBindPhone() { return BitStatesUtils.hasState(bitState, BitStatesUtils.OP_BIND_PHONE); } public boolean getIsBindEmail() { return BitStatesUtils.hasState(bitState, BitStatesUtils.OP_BIND_EMAIL); } public boolean getBaseInfo() { return BitStatesUtils.hasState(bitState, BitStatesUtils.OP_BASE_INFO); } public boolean getRealAuth() { return BitStatesUtils.hasState(bitState, BitStatesUtils.OP_REAL_AUTH); } public boolean getVedioAuth() { return BitStatesUtils.hasState(bitState, BitStatesUtils.OP_VEDIO_AUTH); } public boolean getHasBidRequest() { return BitStatesUtils.hasState(bitState, BitStatesUtils.OP_HAS_BIDRQUEST); } /** * 获取用户真实名字的隐藏字符串,只显示姓氏 * * @param 真实名字 * @return */ public String getAnonymousRealName() { if (StringUtils.hasLength(realName)) { int len = realName.length(); String replace = ""; replace += realName.charAt(0); for (int i = 1; i < len; i++) { replace += "*"; } return replace; } return realName; } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/pojo/Orders.java ================================================ package com.geekq.admin.pojo; public class Orders { private String id; private String orderNum; private String itemId; public String getId() { return id; } public void setId(String id) { this.id = id == null ? null : id.trim(); } public String getOrderNum() { return orderNum; } public void setOrderNum(String orderNum) { this.orderNum = orderNum == null ? null : orderNum.trim(); } public String getItemId() { return itemId; } public void setItemId(String itemId) { this.itemId = itemId == null ? null : itemId.trim(); } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/pojo/OrdersExample.java ================================================ package com.geekq.admin.pojo; import java.util.ArrayList; import java.util.List; public class OrdersExample { protected String orderByClause; protected boolean distinct; protected List oredCriteria; public OrdersExample() { oredCriteria = new ArrayList(); } public String getOrderByClause() { return orderByClause; } public void setOrderByClause(String orderByClause) { this.orderByClause = orderByClause; } public boolean isDistinct() { return distinct; } public void setDistinct(boolean distinct) { this.distinct = distinct; } public List getOredCriteria() { return oredCriteria; } public void or(Criteria criteria) { oredCriteria.add(criteria); } public Criteria or() { Criteria criteria = createCriteriaInternal(); oredCriteria.add(criteria); return criteria; } public Criteria createCriteria() { Criteria criteria = createCriteriaInternal(); if (oredCriteria.size() == 0) { oredCriteria.add(criteria); } return criteria; } protected Criteria createCriteriaInternal() { Criteria criteria = new Criteria(); return criteria; } public void clear() { oredCriteria.clear(); orderByClause = null; distinct = false; } protected abstract static class GeneratedCriteria { protected List criteria; protected GeneratedCriteria() { super(); criteria = new ArrayList(); } public boolean isValid() { return criteria.size() > 0; } public List getAllCriteria() { return criteria; } public List getCriteria() { return criteria; } protected void addCriterion(String condition) { if (condition == null) { throw new RuntimeException("Value for condition cannot be null"); } criteria.add(new Criterion(condition)); } protected void addCriterion(String condition, Object value, String property) { if (value == null) { throw new RuntimeException("Value for " + property + " cannot be null"); } criteria.add(new Criterion(condition, value)); } protected void addCriterion(String condition, Object value1, Object value2, String property) { if (value1 == null || value2 == null) { throw new RuntimeException("Between values for " + property + " cannot be null"); } criteria.add(new Criterion(condition, value1, value2)); } public Criteria andIdIsNull() { addCriterion("id is null"); return (Criteria) this; } public Criteria andIdIsNotNull() { addCriterion("id is not null"); return (Criteria) this; } public Criteria andIdEqualTo(String value) { addCriterion("id =", value, "id"); return (Criteria) this; } public Criteria andIdNotEqualTo(String value) { addCriterion("id <>", value, "id"); return (Criteria) this; } public Criteria andIdGreaterThan(String value) { addCriterion("id >", value, "id"); return (Criteria) this; } public Criteria andIdGreaterThanOrEqualTo(String value) { addCriterion("id >=", value, "id"); return (Criteria) this; } public Criteria andIdLessThan(String value) { addCriterion("id <", value, "id"); return (Criteria) this; } public Criteria andIdLessThanOrEqualTo(String value) { addCriterion("id <=", value, "id"); return (Criteria) this; } public Criteria andIdLike(String value) { addCriterion("id like", value, "id"); return (Criteria) this; } public Criteria andIdNotLike(String value) { addCriterion("id not like", value, "id"); return (Criteria) this; } public Criteria andIdIn(List values) { addCriterion("id in", values, "id"); return (Criteria) this; } public Criteria andIdNotIn(List values) { addCriterion("id not in", values, "id"); return (Criteria) this; } public Criteria andIdBetween(String value1, String value2) { addCriterion("id between", value1, value2, "id"); return (Criteria) this; } public Criteria andIdNotBetween(String value1, String value2) { addCriterion("id not between", value1, value2, "id"); return (Criteria) this; } public Criteria andOrderNumIsNull() { addCriterion("order_num is null"); return (Criteria) this; } public Criteria andOrderNumIsNotNull() { addCriterion("order_num is not null"); return (Criteria) this; } public Criteria andOrderNumEqualTo(String value) { addCriterion("order_num =", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumNotEqualTo(String value) { addCriterion("order_num <>", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumGreaterThan(String value) { addCriterion("order_num >", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumGreaterThanOrEqualTo(String value) { addCriterion("order_num >=", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumLessThan(String value) { addCriterion("order_num <", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumLessThanOrEqualTo(String value) { addCriterion("order_num <=", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumLike(String value) { addCriterion("order_num like", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumNotLike(String value) { addCriterion("order_num not like", value, "orderNum"); return (Criteria) this; } public Criteria andOrderNumIn(List values) { addCriterion("order_num in", values, "orderNum"); return (Criteria) this; } public Criteria andOrderNumNotIn(List values) { addCriterion("order_num not in", values, "orderNum"); return (Criteria) this; } public Criteria andOrderNumBetween(String value1, String value2) { addCriterion("order_num between", value1, value2, "orderNum"); return (Criteria) this; } public Criteria andOrderNumNotBetween(String value1, String value2) { addCriterion("order_num not between", value1, value2, "orderNum"); return (Criteria) this; } public Criteria andItemIdIsNull() { addCriterion("item_id is null"); return (Criteria) this; } public Criteria andItemIdIsNotNull() { addCriterion("item_id is not null"); return (Criteria) this; } public Criteria andItemIdEqualTo(String value) { addCriterion("item_id =", value, "itemId"); return (Criteria) this; } public Criteria andItemIdNotEqualTo(String value) { addCriterion("item_id <>", value, "itemId"); return (Criteria) this; } public Criteria andItemIdGreaterThan(String value) { addCriterion("item_id >", value, "itemId"); return (Criteria) this; } public Criteria andItemIdGreaterThanOrEqualTo(String value) { addCriterion("item_id >=", value, "itemId"); return (Criteria) this; } public Criteria andItemIdLessThan(String value) { addCriterion("item_id <", value, "itemId"); return (Criteria) this; } public Criteria andItemIdLessThanOrEqualTo(String value) { addCriterion("item_id <=", value, "itemId"); return (Criteria) this; } public Criteria andItemIdLike(String value) { addCriterion("item_id like", value, "itemId"); return (Criteria) this; } public Criteria andItemIdNotLike(String value) { addCriterion("item_id not like", value, "itemId"); return (Criteria) this; } public Criteria andItemIdIn(List values) { addCriterion("item_id in", values, "itemId"); return (Criteria) this; } public Criteria andItemIdNotIn(List values) { addCriterion("item_id not in", values, "itemId"); return (Criteria) this; } public Criteria andItemIdBetween(String value1, String value2) { addCriterion("item_id between", value1, value2, "itemId"); return (Criteria) this; } public Criteria andItemIdNotBetween(String value1, String value2) { addCriterion("item_id not between", value1, value2, "itemId"); return (Criteria) this; } } public static class Criteria extends GeneratedCriteria { protected Criteria() { super(); } } public static class Criterion { private String condition; private Object value; private Object secondValue; private boolean noValue; private boolean singleValue; private boolean betweenValue; private boolean listValue; private String typeHandler; protected Criterion(String condition) { super(); this.condition = condition; this.typeHandler = null; this.noValue = true; } protected Criterion(String condition, Object value, String typeHandler) { super(); this.condition = condition; this.value = value; this.typeHandler = typeHandler; if (value instanceof List) { this.listValue = true; } else { this.singleValue = true; } } protected Criterion(String condition, Object value) { this(condition, value, null); } protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { super(); this.condition = condition; this.value = value; this.secondValue = secondValue; this.typeHandler = typeHandler; this.betweenValue = true; } protected Criterion(String condition, Object value, Object secondValue) { this(condition, value, secondValue, null); } public String getCondition() { return condition; } public Object getValue() { return value; } public Object getSecondValue() { return secondValue; } public boolean isNoValue() { return noValue; } public boolean isSingleValue() { return singleValue; } public boolean isBetweenValue() { return betweenValue; } public boolean isListValue() { return listValue; } public String getTypeHandler() { return typeHandler; } } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/query/IpLogQueryObject.java ================================================ package com.geekq.admin.query; import com.geekq.common.utils.DateUtil; import lombok.Getter; import lombok.Setter; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; /** * IpLog查询对象 * * @author 邱润泽 */ @Setter @Getter public class IpLogQueryObject extends QueryObject { private Date beginDate; private Date endDate; private String username; private int userType = -1; private boolean like; private int state = -1; @DateTimeFormat(pattern = "yyyy-MM-dd") public void setBeginDate(Date beginDate) { this.beginDate = beginDate; } public Date getEndDate() { if (endDate != null) { return DateUtil.endOfDay(endDate); } return null; } @DateTimeFormat(pattern = "yyyy-MM-dd") public void setEndDate(Date endDate) { this.endDate = endDate; } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/query/PageResult.java ================================================ package com.geekq.admin.query; import java.util.ArrayList; import java.util.List; public class PageResult { private Integer totalCount; private Integer pageSize = 10; private Integer currentPage = 1; private List result; public PageResult() { } public PageResult(Integer totalCount, Integer pageSize, Integer currentPage, List result) { super(); this.totalCount = totalCount; this.pageSize = pageSize; this.currentPage = currentPage; this.result = result; } public static PageResult empty(int pageSize) { return new PageResult(0, pageSize, 1, new ArrayList()); } public Integer getTotalPage() { return Math.max((totalCount + pageSize - 1) / pageSize, 1); } public Integer getPrev() { return Math.max(currentPage - 1, 1); } public Integer getNext() { return Math.min(currentPage + 1, getTotalPage()); } public Integer getTotalCount() { return totalCount; } public List getResult() { return result; } public Integer getCurrentPage() { return currentPage; } public void setCurrentPage(Integer currentPage) { this.currentPage = currentPage; } public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/query/QueryObject.java ================================================ package com.geekq.admin.query; import lombok.Getter; import lombok.Setter; @Getter @Setter public class QueryObject { private Integer currentPage = 1; private Integer pageSize = 10; public int getStart() { return (currentPage - 1) * pageSize; } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/query/SystemDictionaryQueryObject.java ================================================ package com.geekq.admin.query; import lombok.Getter; import lombok.Setter; import org.springframework.util.StringUtils; @Getter @Setter public class SystemDictionaryQueryObject extends QueryObject { private String keyword; private Long parentId; public String getKeyword() { return StringUtils.hasLength(keyword) ? keyword : null; } } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/service/IAccountService.java ================================================ package com.geekq.admin.service; import com.geekq.admin.entity.Account; import java.util.List; public interface IAccountService { void update(Account account); Account get(Long id); void recreateAbstractInfo(); List listAll(); } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/service/IIpLogService.java ================================================ package com.geekq.admin.service; import com.geekq.admin.entity.IpLog; import com.geekq.admin.query.IpLogQueryObject; import com.geekq.admin.query.PageResult; public interface IIpLogService { PageResult query(IpLogQueryObject qo); void insert(IpLog ipLog); } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/service/ILogininfoService.java ================================================ package com.geekq.admin.service; import com.geekq.admin.entity.Logininfo; import com.geekq.common.utils.resultbean.ResultGeekQ; import java.util.List; import java.util.Map; public interface ILogininfoService { /** * 注册 * * @param username * @param password */ void register(String username, String password); /** * 检查是否有重复的用户名 */ boolean checkUsername(String name, int userType); /** * 用户登陆 * * @param name * @param password * @return */ ResultGeekQ login(String name, String password, int userType, String ip); /** * 是否有管理员 * * @return */ boolean hasAdmin(); /** * 创建默认的管理员 */ void createDefaultAdmin(); /** * 查询用户的id和name * * @param word * @param userType * @return */ List> autoComplate(String word, int userType); } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/service/ISystemDictionaryService.java ================================================ package com.geekq.admin.service; import com.geekq.admin.entity.SystemDictionary; import com.geekq.admin.entity.SystemDictionaryItem; import com.geekq.admin.query.PageResult; import com.geekq.admin.query.SystemDictionaryQueryObject; import java.util.List; public interface ISystemDictionaryService { PageResult queryDic(SystemDictionaryQueryObject qo); void saveOrUpdate(SystemDictionary sd); PageResult queryDicItem(SystemDictionaryQueryObject qo); void saveOrUpdateItem(SystemDictionaryItem item); List listDics(); List queryBySn(String sn); } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/service/IUserService.java ================================================ package com.geekq.admin.service; import com.geekq.admin.entity.Userinfo; public interface IUserService { void update(Userinfo userinfo); Userinfo get(Long id); boolean bindPhone(String phoneNumber, String verifyCode); /** * 修改基本信息 * * @param userinfo */ void updateBasicInfo(Userinfo userinfo); } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/service/OrdersService.java ================================================ package com.geekq.admin.service; import com.geekq.admin.pojo.Orders; public interface OrdersService { /** * @Description: 根据订单id查询订单 */ public Orders getOrder(String orderId); /** * @Description: 下订单 */ public boolean createOrder(String itemId); } ================================================ FILE: miaosha-admin/miaosha-admin-api/src/main/java/com/geekq/admin/service/RedisCacheStorageService.java ================================================ package com.geekq.admin.service; import com.geekq.admin.entity.Logininfo; public interface RedisCacheStorageService { /** * 在redis数据库中插入 key 和value * * @param key * @param value * @return */ boolean set(String key, V value); Logininfo get(String key); } ================================================ FILE: miaosha-admin/miaosha-admin-common/.gitignore ================================================ /.classpath /.project /.settings/ /target/ ================================================ FILE: miaosha-admin/miaosha-admin-common/pom.xml ================================================ 4.0.0 com.geekq miaosha-admin ${revision} miaosha-admin-common ${revision} org.apache.commons commons-lang3 com.fasterxml.jackson.core jackson-databind javax.validation validation-api org.projectlombok lombok provided com.alibaba fastjson org.springframework spring-context commons-codec commons-codec ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/enums/Constants.java ================================================ package com.geekq.common.enums; /** * @author 邱润泽 * 常用数据静态变量类型集合 */ public class Constants { public static final int STATE_NORMAL = 0; public static final int STATE_LOCK = 1; public static final int STATE_DELETE = -1; public static final int USERTYPE_NORMAL = 0;//前段用户 public static final int USERTYPE_SYSTEM = 1;//后台用户 } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/enums/MessageStatus.java ================================================ package com.geekq.common.enums; public class MessageStatus { public static final Integer ZORE = 0; /** * 消息类型 */ public enum messageType { maiosha_message("秒杀消息"), buy_message("购买消息"), system_message("系统消息"); private String message; private messageType(String message) { this.message = message; } public String getMessage() { return message; } } /** * 消息内容 */ public enum ContentEnum { system_message_register(7000, "尊敬的用户你好,你已经成功注册!"), system_message_register_head(7001, "注册成功"); private int code; private String message; private ContentEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } } /** * 消息类型 */ public enum sendType { // maiosha_message("秒杀消息"), // buy_message("购买消息"), // system_message("系统消息"); // private String message; // // private messageType(String message){ // this.message = message; // } // // public String getMessage() { // return message; // } } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/enums/OrderStatusEnum.java ================================================ package com.geekq.common.enums; /** * @Description: 订单状态 */ public enum OrderStatusEnum { WAIT_PAY(10, "待付款"), // 代付款 PAYING(20, "付款中"), // 付款中 PAID(30, "已付款"), // 已付款 PAID_FAILD(40, "付款失败"), // 付款失败 CANCELED(50, "已取消"), // 已取消 CLOSED(60, "交易关闭"); // 超时未支付, 交易关闭 public final int key; public final String value; OrderStatusEnum(int key, String value) { this.key = key; this.value = value; } public static String getName(int key) { for (OrderStatusEnum status : OrderStatusEnum.values()) { if (status.getKey() == key) { return status.value; } } return null; } public int getKey() { return key; } public String getValue() { return value; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/enums/ResultStatus.java ================================================ package com.geekq.common.enums; /** * 普通返回类 * 1打头 系统系列错误 * 2 注册登录系列错误 * 3 check 系列错误 * 4 秒杀错误 * 5 商品错误 * 6 订单错误 * * @author qiurunze */ public enum ResultStatus { SUCCESS(0, "成功"), FAILD(-1, "失败"), EXCEPTION(-1, "系统异常"), PARAM_ERROR(10000, "参数错误"), SYSTEM_ERROR(10001, "系统错误"), FILE_NOT_EXIST(10002, "文件不存在"), FILE_NOT_DOWNLOAD(10003, "文件没有下载"), FILE_NOT_GENERATE(10004, "文件没有生成"), FILE_NOT_STORAGE(10005, "文件没有入库"), SYSTEM_DB_ERROR(10006, "数据库系统错误"), FILE_ALREADY_DOWNLOAD(10007, "文件已经下载"), DATA_ALREADY_PEXISTS(10008, "数据已经存在"), /** * 注册登录 */ RESIGETR_SUCCESS(20000, "注册成功!"), RESIGETER_FAIL(200001, "注册失败!"), CODE_FAIL(200002, "验证码不一致!"), RESIGETER_NICKNAMEEXIST(200003, "用户名已经存在!"), LOGIN_FIAL(200004, "登录失败!"), /** * check */ BIND_ERROR(30001, "参数校验异常:%s"), ACCESS_LIMIT_REACHED(30002, "请求非法!"), REQUEST_ILLEGAL(30004, "访问太频繁!"), SESSION_ERROR(30005, "Session不存在或者已经失效!"), PASSWORD_EMPTY(30006, "登录密码不能为空!"), MOBILE_EMPTY(30007, "手机号不能为空!"), MOBILE_ERROR(30008, "手机号格式错误!"), MOBILE_NOT_EXIST(30009, "手机号不存在!"), PASSWORD_ERROR(30010, "密码错误!"), USER_NOT_EXIST(30011, "用户不存在!"), /** * 订单模块 */ ORDER_NOT_EXIST(60001, "订单不存在"), /** * 秒杀模块 */ MIAO_SHA_OVER(40001, "商品已经秒杀完毕"), REPEATE_MIAOSHA(40002, "不能重复秒杀"), MIAOSHA_FAIL(40003, "秒杀失败"); /** * 商品模块 */ private int code; private String message; private ResultStatus(int code, String message) { this.code = code; this.message = message; } private ResultStatus(Object... args) { this.message = String.format(this.message, args); } public int getCode() { return this.code; } public void setCode(int code) { this.code = code; } public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public String getName() { return this.name(); } public String getOutputName() { return this.name(); } public String toString() { return this.getName(); } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/enums/SexEnum.java ================================================ package com.geekq.common.enums; /** * @Description: 男女枚举 */ public enum SexEnum { GIRL(0), // 女 BOY(1), // 男 SECRET(2); // 保密 public final int value; SexEnum(int value) { this.value = value; } public int getValue() { return value; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/enums/YesOrNo.java ================================================ package com.geekq.common.enums; /** * @Description: 是否枚举 */ public enum YesOrNo { YES(1), // 是 有错误 NO(0); // 否 无错误 public final int value; YesOrNo(int value) { this.value = value; } public int getValue() { return value; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/Constanst.java ================================================ package com.geekq.common.utils; public class Constanst { public static String CLOSE_ORDER_INFO_TASK_LOCK = "CLOSE_ORDER_INFO_KEY"; public static String COUNTLOGIN = "count:login"; public enum orderStaus { ORDER_NOT_PAY("新建未支付"); private String name; orderStaus(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/DBContextUtil.java ================================================ package com.geekq.common.utils; public class DBContextUtil { public static final String DBMASTER = "dbmaster"; public static final String DBREAD = "dbread"; private static ThreadLocal dbPools = new ThreadLocal<>(); public static String getDB() { return dbPools.get(); } public static void setDB(String db) { dbPools.set(db); } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/DateUtil.java ================================================ package com.geekq.common.utils; import org.apache.commons.lang3.time.DateUtils; import java.util.Calendar; import java.util.Date; public class DateUtil { public static Date endOfDay(Date d) { return DateUtils.addSeconds( DateUtils.addDays(DateUtils.truncate(d, Calendar.DATE), 1), -1); } public static long getSecondsBetweenDates(Date d1, Date d2) { return Math.abs((d1.getTime() - d2.getTime()) / 1000); } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/JsonUtils.java ================================================ package com.geekq.common.utils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; /** * @Description: 自定义响应结构, 转换类 */ public class JsonUtils { // 定义jackson对象 private static final ObjectMapper MAPPER = new ObjectMapper(); /** * 将对象转换成json字符串。 *

Title: pojoToJson

*

Description:

* * @param data * @return */ public static String objectToJson(Object data) { try { String string = MAPPER.writeValueAsString(data); return string; } catch (JsonProcessingException e) { e.printStackTrace(); } return null; } /** * 将json结果集转化为对象 * * @param jsonData json数据 * @param clazz 对象中的object类型 * @return */ public static T jsonToPojo(String jsonData, Class beanType) { try { T t = MAPPER.readValue(jsonData, beanType); return t; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将json数据转换成pojo对象list *

Title: jsonToList

*

Description:

* * @param jsonData * @param beanType * @return */ public static List jsonToList(String jsonData, Class beanType) { JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); try { List list = MAPPER.readValue(jsonData, javaType); return list; } catch (Exception e) { e.printStackTrace(); } return null; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/SnowflakeIdWorker.java ================================================ package com.geekq.common.utils; /** * Twitter_Snowflake
* SnowFlake的结构如下(每部分用-分开):
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
* 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
* 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截) * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69
* 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId
* 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号
* 加起来刚好64位,为一个Long型。
* SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。 */ public class SnowflakeIdWorker { // ==============================Fields=========================================== /** * 开始时间截 (2015-01-01) */ private final long twepoch = 1420041600000L; /** * 机器id所占的位数 */ private final long workerIdBits = 5L; /** * 数据标识id所占的位数 */ private final long datacenterIdBits = 5L; /** * 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ private final long maxWorkerId = -1L ^ (-1L << workerIdBits); /** * 支持的最大数据标识id,结果是31 */ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); /** * 序列在id中占的位数 */ private final long sequenceBits = 12L; /** * 机器ID向左移12位 */ private final long workerIdShift = sequenceBits; /** * 数据标识id向左移17位(12+5) */ private final long datacenterIdShift = sequenceBits + workerIdBits; /** * 时间截向左移22位(5+5+12) */ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; /** * 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */ private final long sequenceMask = -1L ^ (-1L << sequenceBits); /** * 工作机器ID(0~31) */ private long workerId; /** * 数据中心ID(0~31) */ private long datacenterId; /** * 毫秒内序列(0~4095) */ private long sequence = 0L; /** * 上次生成ID的时间截 */ private long lastTimestamp = -1L; //==============================Constructors===================================== /** * 构造函数 * * @param workerId 工作ID (0~31) * @param datacenterId 数据中心ID (0~31) */ public SnowflakeIdWorker(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; } /** * 生成订单唯一ID * * @param workerId * @param datacenterId * @return */ public static long getOrderId(long workerId, long datacenterId) { SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0); return idWorker.nextId(); } /** * 获得下一个ID (该方法是线程安全的) * * @return SnowflakeId */ public synchronized long nextId() { long timestamp = timeGen(); //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 if (timestamp < lastTimestamp) { throw new RuntimeException( String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } //如果是同一时间生成的,则进行毫秒内序列 if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; //毫秒内序列溢出 if (sequence == 0) { //阻塞到下一个毫秒,获得新的时间戳 timestamp = tilNextMillis(lastTimestamp); } } //时间戳改变,毫秒内序列重置 else { sequence = 0L; } //上次生成ID的时间截 lastTimestamp = timestamp; //移位并通过或运算拼到一起组成64位的ID return ((timestamp - twepoch) << timestampLeftShift) // | (datacenterId << datacenterIdShift) // | (workerId << workerIdShift) // | sequence; } /** * 阻塞到下一个毫秒,直到获得新的时间戳 * * @param lastTimestamp 上次生成ID的时间截 * @return 当前时间戳 */ protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } //==============================Test============================================= /** * 返回以毫秒为单位的当前时间 * * @return 当前时间(毫秒) */ protected long timeGen() { return System.currentTimeMillis(); } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/ValidatorUtil.java ================================================ package com.geekq.common.utils; import org.apache.commons.lang3.StringUtils; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ValidatorUtil { private static final Pattern mobile_pattern = Pattern.compile("1\\d{10}"); public static boolean isMobile(String src) { if (StringUtils.isEmpty(src)) { return false; } Matcher m = mobile_pattern.matcher(src); return m.matches(); } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/md5/MD5Utils.java ================================================ package com.geekq.common.utils.md5; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; import java.security.SecureRandom; /** * @author 邱润泽 */ public class MD5Utils { private static String getSalt = getSaltT(); public static final String getSaltT() { SecureRandom random = new SecureRandom(); byte bytes[] = new byte[15]; random.nextBytes(bytes); String salt = Base64.encodeBase64String(bytes); return salt; } public static String MD5(String keyName) { /** * 返回16 */ return DigestUtils.md5Hex(keyName); } /** * 测试使用 * * @param inputPass * @return */ public static String inputPassFormPass(String inputPass) { String str = "" + getSalt.charAt(0) + getSalt.charAt(2) + inputPass + getSalt.charAt(4) + getSalt.charAt(6); return MD5(str); } /** * 盐值salt 随机 二次加密 * * @param inputPass * @return */ public static String formPassFormPass(String inputPass) { String str = "" + getSalt.charAt(0) + getSalt.charAt(2) + inputPass + getSalt.charAt(4) + getSalt.charAt(6); return MD5(str); } /** * 第二次md5--反解密 用户登录验证 --- salt 可随机 * * @param formPass * @param salt * @return */ public static String formPassToDBPass(String formPass, String salt) { String str = "" + salt.charAt(0) + salt.charAt(2) + formPass + salt.charAt(4) + salt.charAt(6); return MD5(str); } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/numcal/BidConst.java ================================================ package com.geekq.common.utils.numcal; import java.math.BigDecimal; /** * 系统需要的常量 * * @author 邱润泽 */ public class BidConst { public static final int DISPLAY_SCALE = 2;//显示精度 public static final int CAL_SCALE = 8;//计算精度 public static final int STORE_SCALE = 4;//保存精度 public static final BigDecimal ZERO = new BigDecimal("0.0000");//系统中需要的zero public static final BigDecimal DEFALUT_BORROWLIMITAMOUNT = new BigDecimal( "2000.0000");//初始用户授信额度 public static final BigDecimal ACCOUNT_MANAGER_CHARGE_RATE = new BigDecimal("0.0500"); public static final String DEFAULT_ADMIN_NAME = "admin"; public static final String DEFAULT_ADMIN_PASSWORD = "1111"; public static final int CREDIT_BORROW_SCORE = 30;//信用信用分数 public final static int RETURN_TYPE_MONTH_INTEREST_PRINCIPAL = 0; // 还款方式 按月分期还款(等额本息) public final static int RETURN_TYPE_MONTH_INTEREST = 1; // 还款方式 按月到期还款(每月还利息,到期还本息) public final static int BIDREQUEST_TYPE_NORMAL = 0; // 普通信用标 public final static int BIDREQUEST_STATE_PUBLISH_PENDING = 0; // 待发布 public final static int BIDREQUEST_STATE_BIDDING = 1; // 招标中 public final static int BIDREQUEST_STATE_UNDO = 2; // 已撤销 public final static int BIDREQUEST_STATE_BIDDING_OVERDUE = 3; // 流标 public final static int BIDREQUEST_STATE_APPROVE_PENDING_1 = 4; // 满标1审 public final static int BIDREQUEST_STATE_APPROVE_PENDING_2 = 5; // 满标2审 public final static int BIDREQUEST_STATE_REJECTED = 6; // 满标审核被拒绝 public final static int BIDREQUEST_STATE_PAYING_BACK = 7; // 还款中 public final static int BIDREQUEST_STATE_COMPLETE_PAY_BACK = 8; // 已还清 public final static int BIDREQUEST_STATE_PAY_BACK_OVERDUE = 9; // 逾期 public final static int BIDREQUEST_STATE_PUBLISH_REFUSE = 10; // 发标审核拒绝状态 public static final BigDecimal SMALLEST_BID_AMOUNT = new BigDecimal("50.0000");//系统规定的最小投标金额 public static final BigDecimal SMALLEST_BIDREQUEST_AMOUNT = new BigDecimal("500.0000");//系统规定的最小借款金额 /** * =============================账户流水类型================================ */ public final static int ACCOUNT_ACTIONTYPE_DEPOSIT_OFFLINE_LOCAL = 0;// 资金流水类别:线下充值 public final static int ACCOUNT_ACTIONTYPE_WITHDRAW = 1;// 资金流水类别:提现 public final static int ACCOUNT_ACTIONTYPE_BIDREQUEST_SUCCESSFUL = 2;// 资金流水类别:成功借款 public final static int ACCOUNT_ACTIONTYPE_BID_SUCCESSFUL = 3;// 资金流水类别:成功投标 public final static int ACCOUNT_ACTIONTYPE_RETURN_MONEY = 4;// 资金流水类别:还款 public final static int ACCOUNT_ACTIONTYPE_CALLBACK_MONEY = 5;// 资金流水类别:回款 public final static int ACCOUNT_ACTIONTYPE_CHARGE = 6;// 资金流水类别:平台管理费 public final static int ACCOUNT_ACTIONTYPE_INTEREST_SHARE = 7;// 资金流水类别:利息管理费 public final static int ACCOUNT_ACTIONTYPE_WITHDRAW_MANAGE_CHARGE = 8;// 资金流水类别:提现手续费 public final static int ACCOUNT_ACTIONTYPE_RECHARGE_CHARGE = 9;// 资金流水类别:充值手续费 public final static int ACCOUNT_ACTIONTYPE_BID_FREEZED = 10;// 资金流水类别:投标冻结金额 public final static int ACCOUNT_ACTIONTYPE_BID_UNFREEZED = 11;// 资金流水类别:取消投标冻结金额 public final static int ACCOUNT_ACTIONTYPE_WITHDRAW_FREEZED = 12;// 资金流水类别:提现申请冻结金额 public final static int ACCOUNT_ACTIONTYPE_WITHDRAW_UNFREEZED = 13;// 资金流水类别:提现申请失败取消冻结金额 /** * =========还款状态=============== */ public final static int PAYMENT_STATE_NORMAL = 0; //正常待还 public final static int PAYMENT_STATE_DONE = 1; //已还 public final static int PAYMENT_STATE_OVERDUE = 2; //逾期 /** * ============系统账户流水类型============= */ public final static int SYSTEM_ACCOUNT_NONE = -1; //未指定 public final static int SYSTEM_ACCOUNT_ACTIONTYPE_MANAGE_CHARGE = 1;//系统账户收到账户管理费(借款管理费) public final static int SYSTEM_ACCOUNT_ACTIONTYPE_INTREST_MANAGE_CHARGE = 2;//系统账户收到利息管理费 public final static int SYSTEM_ACCOUNT_ACTIONTYPE_WITHDRAW_MANAGE_CHARGE = 3;//系统账户收到提现手续费 } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/numcal/BitStatesUtils.java ================================================ package com.geekq.common.utils.numcal; /** * 用户状态类,记录用户在平台使用系统中所有的状态。 * * @author 邱润泽 */ public class BitStatesUtils { public final static Long OP_BASIC_INFO = 1L; //用户注册成功的标示,及为默认初始状态 public final static Long OP_BIND_PHONE = 2L; //用户绑定手机状态码 public final static Long OP_BIND_EMAIL = 2L << 1;//用户绑定邮箱 public final static Long OP_BASE_INFO = 2L << 2;//填写基本资料 public final static Long OP_REAL_AUTH = 2L << 3;//用户实名认证 public final static Long OP_VEDIO_AUTH = 2L << 4;//视频认证 public final static Long OP_HAS_BIDRQUEST = 2l << 5;//当前用户有一个借款还在借款流程当中 /** * @param states 所有状态值 * @param value 需要判断状态值 * @return 是否存在 */ public static boolean hasState(long states, long value) { return (states & value) != 0; } /** * @param states 已有状态值 * @param value 需要添加状态值 * @return 新的状态值 */ public static long addState(long states, long value) { if (hasState(states, value)) { return states; } return (states | value); } /** * @param states 已有状态值 * @param value 需要删除状态值 * @return 新的状态值 */ public static long removeState(long states, long value) { if (!hasState(states, value)) { return states; } return states ^ value; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/numcal/CalculateUtil.java ================================================ package com.geekq.common.utils.numcal; import java.math.BigDecimal; import java.math.RoundingMode; /** * 计算器Util * @author 邱润泽 */ public class CalculateUtil { public static final BigDecimal ONE_HUNDRED = new BigDecimal("100.0000"); public static final BigDecimal NUMBER_MONTHS_OF_YEAR = new BigDecimal( "12.0000"); /** * 获取月利率 */ public static BigDecimal getMonthlyRate(BigDecimal yearRate) { if (yearRate == null) return BigDecimal.ZERO; return yearRate.divide(ONE_HUNDRED).divide(NUMBER_MONTHS_OF_YEAR, BidConst.CAL_SCALE, RoundingMode.HALF_UP); } /** * 计算借款总利息 * * @param returnType 还款类型 * @param bidRequestAmount 借款金额 * @param yearRate 年利率 * @param monthes2Return 还款期限 * @return */ public static BigDecimal calTotalInterest(int returnType, BigDecimal bidRequestAmount, BigDecimal yearRate, int monthes2Return) { BigDecimal totalInterest = BigDecimal.ZERO; BigDecimal monthlyRate = getMonthlyRate(yearRate); if (returnType == BidConst.RETURN_TYPE_MONTH_INTEREST_PRINCIPAL) {// 按月分期 // 只借款一个月 if (monthes2Return == 1) { totalInterest = bidRequestAmount.multiply(monthlyRate) .setScale(BidConst.CAL_SCALE, RoundingMode.HALF_UP); } else { BigDecimal temp1 = bidRequestAmount.multiply(monthlyRate); BigDecimal temp2 = (BigDecimal.ONE.add(monthlyRate)) .pow(monthes2Return); BigDecimal temp3 = (BigDecimal.ONE.add(monthlyRate)).pow( monthes2Return).subtract(BigDecimal.ONE); // 算出每月还款 BigDecimal monthToReturnMoney = temp1.multiply(temp2).divide( temp3, BidConst.CAL_SCALE, RoundingMode.HALF_UP); // 算出总还款 BigDecimal totalReturnMoney = monthToReturnMoney .multiply(new BigDecimal(monthes2Return)); // 算出总利息 totalInterest = totalReturnMoney.subtract(bidRequestAmount); } } else if (returnType == BidConst.RETURN_TYPE_MONTH_INTEREST) {// 按月到期 BigDecimal monthlyInterest = DecimalFormatUtil .amountFormat(bidRequestAmount.multiply(monthlyRate)); totalInterest = monthlyInterest.multiply(new BigDecimal( monthes2Return)); } return DecimalFormatUtil.formatBigDecimal(totalInterest, BidConst.STORE_SCALE); } /** * 计算每期利息 * * @param returnType 还款类型 * @param bidRequestAmount 借款金额 * @param yearRate 年利率 * @param monthIndex 第几期 * @param monthes2Return 还款期限 * @return */ public static BigDecimal calMonthlyInterest(int returnType, BigDecimal bidRequestAmount, BigDecimal yearRate, int monthIndex, int monthes2Return) { BigDecimal monthlyInterest = BigDecimal.ZERO; BigDecimal monthlyRate = getMonthlyRate(yearRate); if (returnType == BidConst.RETURN_TYPE_MONTH_INTEREST_PRINCIPAL) {// 按月分期 // 只借款一个月 if (monthes2Return == 1) { monthlyInterest = bidRequestAmount.multiply(monthlyRate) .setScale(BidConst.CAL_SCALE, RoundingMode.HALF_UP); } else { BigDecimal temp1 = bidRequestAmount.multiply(monthlyRate); BigDecimal temp2 = (BigDecimal.ONE.add(monthlyRate)) .pow(monthes2Return); BigDecimal temp3 = (BigDecimal.ONE.add(monthlyRate)).pow( monthes2Return).subtract(BigDecimal.ONE); BigDecimal temp4 = (BigDecimal.ONE.add(monthlyRate)) .pow(monthIndex - 1); // 算出每月还款 BigDecimal monthToReturnMoney = temp1.multiply(temp2).divide( temp3, BidConst.CAL_SCALE, RoundingMode.HALF_UP); // 算出总还款 BigDecimal totalReturnMoney = monthToReturnMoney .multiply(new BigDecimal(monthes2Return)); // 算出总利息 BigDecimal totalInterest = totalReturnMoney .subtract(bidRequestAmount); if (monthIndex < monthes2Return) { monthlyInterest = (temp1.subtract(monthToReturnMoney)) .multiply(temp4).add(monthToReturnMoney) .setScale(BidConst.CAL_SCALE, RoundingMode.HALF_UP); } else if (monthIndex == monthes2Return) { BigDecimal temp6 = BigDecimal.ZERO; // 汇总最后一期之前所有利息之和 for (int i = 1; i < monthes2Return; i++) { BigDecimal temp5 = (BigDecimal.ONE.add(monthlyRate)) .pow(i - 1); monthlyInterest = (temp1.subtract(monthToReturnMoney)) .multiply(temp5) .add(monthToReturnMoney) .setScale(BidConst.CAL_SCALE, RoundingMode.HALF_UP); temp6 = temp6.add(monthlyInterest); } monthlyInterest = totalInterest.subtract(temp6); } } } else if (returnType == BidConst.RETURN_TYPE_MONTH_INTEREST) {// 按月到期 monthlyInterest = DecimalFormatUtil.amountFormat(bidRequestAmount .multiply(monthlyRate)); } return monthlyInterest; } /** * 计算每期还款 * * @param returnType 还款类型 * @param bidRequestAmount 借款金额 * @param yearRate 年利率 * @param monthIndex 第几期 * @param monthes2Return 还款期限 * @return */ public static BigDecimal calMonthToReturnMoney(int returnType, BigDecimal bidRequestAmount, BigDecimal yearRate, int monthIndex, int monthes2Return) { BigDecimal monthToReturnMoney = BigDecimal.ZERO; BigDecimal monthlyRate = getMonthlyRate(yearRate); if (returnType == BidConst.RETURN_TYPE_MONTH_INTEREST_PRINCIPAL) {// 按月分期 if (monthes2Return == 1) { monthToReturnMoney = bidRequestAmount.add( bidRequestAmount.multiply(monthlyRate)).setScale( BidConst.CAL_SCALE, RoundingMode.HALF_UP); } else { BigDecimal temp1 = bidRequestAmount.multiply(monthlyRate); BigDecimal temp2 = (BigDecimal.ONE.add(monthlyRate)) .pow(monthes2Return); BigDecimal temp3 = (BigDecimal.ONE.add(monthlyRate)).pow( monthes2Return).subtract(BigDecimal.ONE); // 算出每月还款 monthToReturnMoney = temp1.multiply(temp2).divide(temp3, BidConst.CAL_SCALE, RoundingMode.HALF_UP); } } else if (returnType == BidConst.RETURN_TYPE_MONTH_INTEREST) {// 按月到期 BigDecimal monthlyInterest = bidRequestAmount.multiply(monthlyRate) .setScale(BidConst.CAL_SCALE, RoundingMode.HALF_UP); if (monthIndex == monthes2Return) { monthToReturnMoney = bidRequestAmount.add(monthlyInterest) .setScale(BidConst.CAL_SCALE, RoundingMode.HALF_UP); } else if (monthIndex < monthes2Return) { monthToReturnMoney = monthlyInterest; } } return DecimalFormatUtil.formatBigDecimal(monthToReturnMoney, BidConst.STORE_SCALE); } /** * 计算一次投标实际获得的利息=投标金额/借款金额 *总利息 * * @param bidRequestAmount 借款金额 * @param monthes2Return 还款期数 * @param yearRate 年利率 * @param returnType 还款类型 * @param acturalBidAmount 投标金额 * @return */ public static BigDecimal calBidInterest(BigDecimal bidRequestAmount, int monthes2Return, BigDecimal yearRate, int returnType, BigDecimal acturalBidAmount) { // 借款产生的总利息 BigDecimal totalInterest = calTotalInterest(returnType, bidRequestAmount, yearRate, monthes2Return); // 所占比例 BigDecimal proportion = acturalBidAmount.divide(bidRequestAmount, BidConst.CAL_SCALE, RoundingMode.HALF_UP); BigDecimal bidInterest = totalInterest.multiply(proportion); return DecimalFormatUtil.formatBigDecimal(bidInterest, BidConst.STORE_SCALE); } /** * 计算利息管理费 * * @param interest * 利息 * @param interestManagerChargeRate * 利息管理费比例 * @return */ /** public static BigDecimal calInterestManagerCharge(BigDecimal interest) { return DecimalFormatUtil.formatBigDecimal( interest.multiply(BidConst.INTEREST_MANAGER_CHARGE_RATE), BidConst.SCALE); } */ /** * 计算借款管理费 * * @param bidRequestAmount 借款金额 * @return */ public static BigDecimal calAccountManagementCharge( BigDecimal bidRequestAmount) { BigDecimal accountManagementCharge = DecimalFormatUtil .formatBigDecimal(bidRequestAmount .multiply(BidConst.ACCOUNT_MANAGER_CHARGE_RATE), BidConst.CAL_SCALE); return accountManagementCharge; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/numcal/DecimalFormatUtil.java ================================================ package com.geekq.common.utils.numcal; import java.math.BigDecimal; import java.math.RoundingMode; /** * 大数字格式化工具类 * * @author 邱润泽 */ public class DecimalFormatUtil { //金额 public static BigDecimal amountFormat(BigDecimal number) { number = number.setScale(BidConst.STORE_SCALE, RoundingMode.HALF_UP); return number; } //利率 public static BigDecimal rateFormat(BigDecimal number) { number = number.setScale(BidConst.STORE_SCALE, RoundingMode.HALF_UP); return number; } public static BigDecimal decimalRateFormat(BigDecimal number) { return number.multiply(BigDecimal.valueOf(100)); } //月利率 public static BigDecimal monthRateFormat(BigDecimal number) { return number.multiply(BigDecimal.valueOf(100)).divide( BigDecimal.valueOf(12), BidConst.CAL_SCALE, RoundingMode.HALF_UP); } public static BigDecimal formatBigDecimal(BigDecimal data, int scal) { if (null == data) return new BigDecimal(0.00); return data.setScale(scal, BigDecimal.ROUND_HALF_UP); } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/resultbean/AbstractResult.java ================================================ package com.geekq.common.utils.resultbean; import com.geekq.common.enums.ResultStatus; public class AbstractResult { private ResultStatus status; private int code; private String message; AbstractResult() { } protected AbstractResult(ResultStatus status, String message) { this.code = status.getCode(); this.status = status; this.message = message; } protected AbstractResult(ResultStatus status) { this.code = status.getCode(); this.message = status.getMessage(); this.status = status; } public static boolean isSuccess(AbstractResult result) { return result != null && result.status == ResultStatus.SUCCESS && result.getCode() == ResultStatus.SUCCESS.getCode(); } public AbstractResult withError(ResultStatus status) { this.status = status; return this; } public AbstractResult withError(String message) { this.status = ResultStatus.SYSTEM_ERROR; this.message = message; return this; } public AbstractResult withError(int code, String message) { this.status = ResultStatus.SYSTEM_ERROR; this.code = code; this.message = message; return this; } public AbstractResult success() { this.status = ResultStatus.SUCCESS; return this; } public ResultStatus getStatus() { return this.status; } public String getMessage() { return this.message == null ? this.status.getMessage() : this.message; } public int getCode() { return this.code; } public void setCode(int code) { this.code = code; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/resultbean/ResultGeekQ.java ================================================ package com.geekq.common.utils.resultbean; import com.geekq.common.enums.ResultStatus; import java.io.Serializable; public class ResultGeekQ extends AbstractResult implements Serializable { private T data; private Integer count; protected ResultGeekQ() { } protected ResultGeekQ(ResultStatus status, String message) { super(status, message); } protected ResultGeekQ(ResultStatus status) { super(status); } public static ResultGeekQ build() { return new ResultGeekQ(ResultStatus.SUCCESS, "构造函数"); } public static ResultGeekQ build(String message) { return new ResultGeekQ(ResultStatus.SUCCESS, message); } public static ResultGeekQ error(ResultStatus status) { return new ResultGeekQ(status); } public T getData() { return data; } public void setData(T data) { this.data = data; } public Integer getCount() { return this.count; } public void setCount(Integer count) { this.count = count; } public void success(T value) { this.success(); this.data = value; this.count = 0; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/utils/resultbean/ResultJSON.java ================================================ package com.geekq.common.utils.resultbean; import lombok.Getter; import lombok.Setter; /** * @author 邱润泽 */ @Getter @Setter public class ResultJSON { private Boolean success = false; private String msg; public ResultJSON() { super(); } public ResultJSON(Boolean success, String msg) { super(); this.success = success; this.msg = msg; } public ResultJSON(String msg) { super(); this.msg = msg; } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/validator/MobileCheck.java ================================================ package com.geekq.common.validator; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = {MobileValidator.class}) public @interface MobileCheck { boolean required() default true; String message() default "手机号码格式有误!"; Class[] groups() default {}; Class[] payload() default {}; } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/validator/MobileValidator.java ================================================ package com.geekq.common.validator; import com.geekq.common.utils.ValidatorUtil; import org.apache.commons.lang3.StringUtils; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class MobileValidator implements ConstraintValidator { private boolean require = false; @Override public void initialize(MobileCheck isMobile) { require = isMobile.required(); } @Override public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) { if (require) { return ValidatorUtil.isMobile(value); } else { if (StringUtils.isEmpty(value)) { return true; } else { return ValidatorUtil.isMobile(value); } } } } ================================================ FILE: miaosha-admin/miaosha-admin-common/src/main/java/com/geekq/common/vo/LoginVo.java ================================================ package com.geekq.common.vo; import com.geekq.common.validator.MobileCheck; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import javax.validation.constraints.NotNull; /** * @author 邱润泽 */ @Setter @Getter @AllArgsConstructor @NoArgsConstructor public class LoginVo { @NotNull @MobileCheck private String mobile; @NotNull private String password; @Override public String toString() { return "LoginVo{" + "mobile='" + mobile + '\'' + ", password='" + password + '\'' + '}'; } } ================================================ FILE: miaosha-admin/miaosha-admin-service/pom.xml ================================================ 4.0.0 com.geekq miaosha-admin ${revision} miaosha-admin-service war org.springframework.data spring-data-redis com.geekq miaosha-admin-api com.geekq miaosha-admin-common com.alibaba dubbo org.apache.zookeeper zookeeper com.github.sgroschupf zkclient org.springframework spring-context org.springframework spring-beans org.springframework spring-webmvc org.springframework spring-jdbc org.springframework spring-aspects redis.clients jedis com.github.miemiedev mybatis-paginator com.github.pagehelper pagehelper mysql mysql-connector-java com.alibaba druid javax.servlet javax.servlet-api provided ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/AccountMapper.java ================================================ package com.geekq.admin.mapper; import com.geekq.admin.entity.Account; import java.util.List; public interface AccountMapper { int deleteByPrimaryKey(Long id); int insert(Account record); Account selectByPrimaryKey(Long id); List selectAll(); int updateByPrimaryKey(Account record); } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/AccountMapper.xml ================================================ delete from account where id = #{id,jdbcType=BIGINT} and version=#{version} insert into account (id,tradePassword, usableAmount, freezedAmount, borrowLimitAmount, version, unReceiveInterest, unReceivePrincipal, unReturnAmount, remainBorrowLimit,abstractInfo) values (#{id},#{tradePassword,jdbcType=VARCHAR}, #{usableAmount,jdbcType=DECIMAL}, #{freezedAmount,jdbcType=DECIMAL}, #{borrowLimitAmount,jdbcType=DECIMAL}, 0, #{unReceiveInterest,jdbcType=DECIMAL}, #{unReceivePrincipal,jdbcType=DECIMAL}, #{unReturnAmount,jdbcType=DECIMAL}, #{remainBorrowLimit,jdbcType=DECIMAL},#{abstractInfo}) update account set tradePassword = #{tradePassword,jdbcType=VARCHAR}, usableAmount = #{usableAmount,jdbcType=DECIMAL}, freezedAmount = #{freezedAmount,jdbcType=DECIMAL}, borrowLimitAmount = #{borrowLimitAmount,jdbcType=DECIMAL}, version = version+1, unReceiveInterest = #{unReceiveInterest,jdbcType=DECIMAL}, unReceivePrincipal = #{unReceivePrincipal,jdbcType=DECIMAL}, unReturnAmount = #{unReturnAmount,jdbcType=DECIMAL}, remainBorrowLimit = #{remainBorrowLimit,jdbcType=DECIMAL}, abstractInfo=#{abstractInfo} where id = #{id,jdbcType=BIGINT} and version=#{version} ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/IpLogMapper.java ================================================ package com.geekq.admin.mapper; import com.geekq.admin.entity.IpLog; import com.geekq.admin.query.IpLogQueryObject; import java.util.List; public interface IpLogMapper { int deleteByPrimaryKey(Long id); int insert(IpLog record); IpLog selectByPrimaryKey(Long id); List selectAll(); int updateByPrimaryKey(IpLog record); int queryForCount(IpLogQueryObject qo); List query(IpLogQueryObject qo); } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/IpLogMapper.xml ================================================ delete from iplog where id = #{id,jdbcType=BIGINT} insert into iplog (ip, loginState, username, loginInfoId, loginType, loginTime) values (#{ip,jdbcType=VARCHAR}, #{loginState,jdbcType=TINYINT}, #{username,jdbcType=VARCHAR}, #{loginInfoId,jdbcType=BIGINT}, #{loginType,jdbcType=TINYINT}, #{loginTime,jdbcType=TIMESTAMP}) update iplog set ip = #{ip,jdbcType=VARCHAR}, loginState = #{loginState,jdbcType=TINYINT}, username = #{username,jdbcType=VARCHAR}, loginInfoId = #{loginInfoId,jdbcType=BIGINT}, loginType = #{loginType,jdbcType=TINYINT}, loginTime = #{loginTime,jdbcType=TIMESTAMP} where id = #{id,jdbcType=BIGINT} id, ip, loginState, username, loginInfoId, loginType, loginTime AND loginTime >=#{beginDate} AND loginTime <=#{endDate} AND username like concat('%',#{username},'%') AND username =#{username} AND loginType =#{userType} AND loginstate = #{state} ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/LogininfoMapper.java ================================================ package com.geekq.admin.mapper; import com.geekq.admin.entity.Logininfo; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; public interface LogininfoMapper { int deleteByPrimaryKey(Long id); int insert(Logininfo record); Logininfo selectByPrimaryKey(Long id); List selectAll(); int updateByPrimaryKey(Logininfo record); int getCountByNickname(@Param("nickname") String nickname, @Param("userType") int userType); Logininfo getLoginInfoByNickname(@Param("nickname") String nickname, @Param("userType") int userType); Logininfo login(@Param("name") String name, @Param("password") String password, @Param("userType") int userType); List> autoComplate(@Param("word") String word, @Param("userType") int userType); } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/LogininfoMapper.xml ================================================ delete from logininfo where id = #{id,jdbcType=BIGINT} insert into logininfo (nickname,password, state,usertype,admin,salt,registerdate,lastlogindate) values (#{nickname,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR},#{state,jdbcType=TINYINT},#{userType},#{admin} ,#{salt},#{registerDate},#{lastLoginDate}) update logininfo set nickname = #{nickname,jdbcType=VARCHAR},password =#{password,jdbcType=VARCHAR}, state = #{state,jdbcType=TINYINT},usertype = #{userType},admin=#{admin},salt = #{salt}, registerdate = #{registerDate},lastlogindate = #{lastLoginDate} where id = #{id,jdbcType=BIGINT} id, nickname, password, state,usertype,admin ,salt , registerdate , lastlogindate ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/OrdersMapper.java ================================================ package com.geekq.admin.mapper; import com.geekq.admin.pojo.Orders; import com.geekq.admin.pojo.OrdersExample; import org.apache.ibatis.annotations.Param; import java.util.List; public interface OrdersMapper { int countByExample(OrdersExample example); int deleteByExample(OrdersExample example); int deleteByPrimaryKey(String id); int insert(Orders record); int insertSelective(Orders record); List selectByExample(OrdersExample example); Orders selectByPrimaryKey(String id); int updateByExampleSelective(@Param("record") Orders record, @Param("example") OrdersExample example); int updateByExample(@Param("record") Orders record, @Param("example") OrdersExample example); int updateByPrimaryKeySelective(Orders record); int updateByPrimaryKey(Orders record); } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/OrdersMapper.xml ================================================ and ${criterion.condition} and ${criterion.condition} #{criterion.value} and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} and ${criterion.condition} #{listItem} and ${criterion.condition} and ${criterion.condition} #{criterion.value} and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} and ${criterion.condition} #{listItem} id, order_num, item_id delete from orders where id = #{id,jdbcType=VARCHAR} delete from orders insert into orders (id, order_num, item_id ) values (#{id,jdbcType=VARCHAR}, #{orderNum,jdbcType=VARCHAR}, #{itemId,jdbcType=VARCHAR} ) insert into orders id, order_num, item_id, #{id,jdbcType=VARCHAR}, #{orderNum,jdbcType=VARCHAR}, #{itemId,jdbcType=VARCHAR}, update orders id = #{record.id,jdbcType=VARCHAR}, order_num = #{record.orderNum,jdbcType=VARCHAR}, item_id = #{record.itemId,jdbcType=VARCHAR}, update orders set id = #{record.id,jdbcType=VARCHAR}, order_num = #{record.orderNum,jdbcType=VARCHAR}, item_id = #{record.itemId,jdbcType=VARCHAR} update orders order_num = #{orderNum,jdbcType=VARCHAR}, item_id = #{itemId,jdbcType=VARCHAR}, where id = #{id,jdbcType=VARCHAR} update orders set order_num = #{orderNum,jdbcType=VARCHAR}, item_id = #{itemId,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR} ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/SystemDictionaryItemMapper.java ================================================ package com.geekq.admin.mapper; import com.geekq.admin.entity.SystemDictionaryItem; import com.geekq.admin.query.SystemDictionaryQueryObject; import org.apache.ibatis.annotations.Param; import java.util.List; public interface SystemDictionaryItemMapper { int deleteByPrimaryKey(Long id); int insert(SystemDictionaryItem record); SystemDictionaryItem selectByPrimaryKey(Long id); List selectAll(); int updateByPrimaryKey(SystemDictionaryItem record); int queryForCount(SystemDictionaryQueryObject qo); List query(SystemDictionaryQueryObject qo); /** * 按照数据字典的目录sn查所有明细 * * @param sn * @return */ List queryBySn(@Param("sn") String sn); } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/SystemDictionaryItemMapper.xml ================================================ delete from systemdictionaryitem where id = #{id,jdbcType=BIGINT} insert into systemdictionaryitem (parentId, title, tvalue,sequence, intro) values (#{parentId,jdbcType=BIGINT}, #{title,jdbcType=VARCHAR},#{tvalue,jdbcType=VARCHAR}, #{sequence,jdbcType=TINYINT}, #{intro,jdbcType=VARCHAR}) update systemdictionaryitem set parentId = #{parentId,jdbcType=BIGINT}, title = #{title,jdbcType=VARCHAR}, tvalue = #{tvalue,jdbcType=VARCHAR}, sequence = #{sequence,jdbcType=TINYINT}, intro = #{intro,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} id, parentId, title, tvalue, sequence, intro AND parentId = #{parentId} AND title LIKE concat('%',#{keyword},'%') ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/SystemDictionaryMapper.java ================================================ package com.geekq.admin.mapper; import com.geekq.admin.entity.SystemDictionary; import com.geekq.admin.query.SystemDictionaryQueryObject; import java.util.List; public interface SystemDictionaryMapper { int deleteByPrimaryKey(Long id); int insert(SystemDictionary record); SystemDictionary selectByPrimaryKey(Long id); List selectAll(); int updateByPrimaryKey(SystemDictionary record); int queryForCount(SystemDictionaryQueryObject qo); List query(SystemDictionaryQueryObject qo); } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/SystemDictionaryMapper.xml ================================================ delete from systemdictionary where id = #{id,jdbcType=BIGINT} insert into systemdictionary (sn, title, intro) values (#{sn,jdbcType=VARCHAR}, #{title,jdbcType=VARCHAR}, #{intro,jdbcType=VARCHAR} ) update systemdictionary set sn = #{sn,jdbcType=VARCHAR}, title = #{title,jdbcType=VARCHAR}, intro = #{intro,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} id, sn, title, intro AND (sn LIKE concat('%',#{keyword},'%') OR title LIKE concat('%',#{keyword},'%')) ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/UserinfoMapper.java ================================================ package com.geekq.admin.mapper; import com.geekq.admin.entity.Userinfo; import org.apache.ibatis.annotations.Param; import java.util.List; public interface UserinfoMapper { int deleteByPrimaryKey(Long id); int insert(Userinfo record); Userinfo selectByPrimaryKey(@Param("id") Long id, @Param("salt") String salt); List selectAll(@Param("salt") String salt); int updateByPrimaryKey(@Param("ui") Userinfo record, @Param("salt") String salt); } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/mapper/UserinfoMapper.xml ================================================ delete from userinfo where id = #{id,jdbcType=BIGINT} and version = #{version} insert into userinfo (id,version, bitState, authScore,email,phoneNumber, incomeGrade_id, marriage_id, kidCount_id, educationBackground_id, houseCondition_id) values (#{id},0, #{bitState,jdbcType=BIGINT}, #{authScore},#{email},#{phoneNumber,jdbcType=VARCHAR}, #{incomeGrade.id,jdbcType=BIGINT}, #{marriage.id,jdbcType=BIGINT}, #{kidCount.id,jdbcType=BIGINT}, #{educationBackground.id,jdbcType=BIGINT}, #{houseCondition.id,jdbcType=BIGINT}) update userinfo set version = version+1, bitState = #{ui.bitState,jdbcType=BIGINT}, realName = AES_ENCRYPT(#{ui.realName,jdbcType=VARCHAR},#{salt}), idNumber = AES_ENCRYPT(#{ui.idNumber,jdbcType=VARCHAR},#{salt}), authScore = #{ui.authScore}, email = #{ui.email}, realauthId=#{ui.realauthId}, phoneNumber = #{ui.phoneNumber,jdbcType=VARCHAR}, incomeGrade_id = #{ui.incomeGrade.id,jdbcType=BIGINT}, marriage_id = #{ui.marriage.id,jdbcType=BIGINT}, kidCount_id = #{ui.kidCount.id,jdbcType=BIGINT}, educationBackground_id = #{ui.educationBackground.id,jdbcType=BIGINT}, houseCondition_id = #{ui.houseCondition.id,jdbcType=BIGINT} where id = #{ui.id,jdbcType=BIGINT} and version = #{ui.version} id, version, bitState, AES_DECRYPT(realName,#{salt}) as realName, AES_DECRYPT(idNumber,#{salt}) as idNumber, phoneNumber, incomeGrade_id, marriage_id, authScore,realauthId,email,kidCount_id, educationBackground_id, houseCondition_id ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/redis/RedisClient.java ================================================ package com.geekq.admin.redis; import com.alibaba.fastjson.JSON; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.util.ResourceBundle; public class RedisClient { /** * 池化管理jedis链接池 */ public static JedisPool jedisPool; static { //读取相关的配置 ResourceBundle resourceBundle = ResourceBundle.getBundle("redis"); int maxActive = Integer.parseInt(resourceBundle.getString("redis.pool.maxActive")); int maxIdle = Integer.parseInt(resourceBundle.getString("redis.pool.maxIdle")); int maxWait = Integer.parseInt(resourceBundle.getString("redis.pool.maxWait")); String ip = resourceBundle.getString("redis.ip"); int port = Integer.parseInt(resourceBundle.getString("redis.port")); JedisPoolConfig config = new JedisPoolConfig(); //设置最大连接数 config.setMaxTotal(maxActive); //设置最大空闲数 config.setMaxIdle(maxIdle); //设置超时时间 config.setMaxWaitMillis(maxWait); //初始化连接池 jedisPool = new JedisPool(config, ip, port); } /** * 向缓存中设置字符串内容 * * @param key key * @param value value * @return * @throws Exception */ public static boolean set(String key, String value) throws Exception { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } finally { jedisPool.returnResource(jedis); } } /** * 向缓存中设置对象 * * @param key * @param value * @return */ public static boolean set(String key, Object value) { Jedis jedis = null; try { String objectJson = JSON.toJSONString(value); jedis = jedisPool.getResource(); jedis.set(key, objectJson); return true; } catch (Exception e) { e.printStackTrace(); return false; } finally { jedisPool.returnResource(jedis); } } /** * 删除缓存中得对象,根据key * * @param key * @return */ public static boolean del(String key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.del(key); return true; } catch (Exception e) { e.printStackTrace(); return false; } finally { jedisPool.returnResource(jedis); } } /** * 根据key 获取内容 * * @param key * @return */ public static Object get(String key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); Object value = jedis.get(key); return value; } catch (Exception e) { e.printStackTrace(); return false; } finally { jedisPool.returnResource(jedis); } } /** * 根据key 获取对象 * * @param key * @return */ public static T get(String key, Class clazz) { Jedis jedis = null; try { jedis = jedisPool.getResource(); String value = jedis.get(key); return JSON.parseObject(value, clazz); } catch (Exception e) { e.printStackTrace(); return null; } finally { jedisPool.returnResource(jedis); } } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/AccountServiceImpl.java ================================================ package com.geekq.admin.service.impl; import com.geekq.admin.entity.Account; import com.geekq.admin.mapper.AccountMapper; import com.geekq.admin.service.IAccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service("accountServiceImpl") public class AccountServiceImpl implements IAccountService { @Autowired private AccountMapper accountMapper; @Override public void update(Account account) { int ret = accountMapper.updateByPrimaryKey(account); // if (ret <= 0) { // throw new RuntimeException("Account对象:" + account.getId() // + " 乐观锁失败!"); // } } @Override public Account get(Long id) { Account account = accountMapper.selectByPrimaryKey(id); // if (!account.checkAbstractInfo()) { // throw new RuntimeException("账户信息被篡改:" + id); // } return account; } /** * 重建account表的摘要信息 */ @Override public void recreateAbstractInfo() { List accounts = this.accountMapper.selectAll(); for (Account account : accounts) { this.accountMapper.updateByPrimaryKey(account); } } @Override public List listAll() { return this.accountMapper.selectAll(); } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/IpLogServiceImpl.java ================================================ package com.geekq.admin.service.impl; import com.geekq.admin.entity.IpLog; import com.geekq.admin.mapper.IpLogMapper; import com.geekq.admin.query.IpLogQueryObject; import com.geekq.admin.query.PageResult; import com.geekq.admin.service.IIpLogService; import com.geekq.common.utils.DBContextUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * @author 邱润泽 */ @Service public class IpLogServiceImpl implements IIpLogService { @Autowired private IpLogMapper ipLogMapper; @Override public PageResult query(IpLogQueryObject qo) { DBContextUtil.setDB(DBContextUtil.DBREAD); int count = this.ipLogMapper.queryForCount(qo); if (count > 0) { List list = this.ipLogMapper.query(qo); return new PageResult(count, qo.getPageSize(), qo.getCurrentPage(), list); } return PageResult.empty(qo.getPageSize()); } @Override public void insert(IpLog ipLog) { this.ipLogMapper.insert(ipLog); } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/LogininfoServiceImpl.java ================================================ package com.geekq.admin.service.impl; import com.geekq.admin.entity.Account; import com.geekq.admin.entity.IpLog; import com.geekq.admin.entity.Logininfo; import com.geekq.admin.entity.Userinfo; import com.geekq.admin.mapper.AccountMapper; import com.geekq.admin.mapper.IpLogMapper; import com.geekq.admin.mapper.LogininfoMapper; import com.geekq.admin.mapper.UserinfoMapper; import com.geekq.admin.service.ILogininfoService; import com.geekq.admin.service.RedisCacheStorageService; import com.geekq.common.enums.Constants; import com.geekq.common.enums.ResultStatus; import com.geekq.common.utils.md5.MD5Utils; import com.geekq.common.utils.resultbean.ResultGeekQ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; import java.util.List; import java.util.Map; /** * @author 邱润泽 */ @Service("logininfoServiceImpl") public class LogininfoServiceImpl implements ILogininfoService { private static final Logger logger = LoggerFactory.getLogger(LogininfoServiceImpl.class); @Autowired private LogininfoMapper loginInfoMapper; @Autowired private IpLogMapper ipLogMapper; @Autowired private UserinfoMapper userinfoMapper; @Autowired private AccountMapper accountMapper; @Autowired private RedisCacheStorageService redisService; @Override public void register(String username, String password) { int count = loginInfoMapper.getCountByNickname(username, Constants.USERTYPE_NORMAL); if (count <= 0) { Logininfo logininfo = new Logininfo(); logininfo.setNickname(username); //获取随机salt String salt = MD5Utils.getSaltT(); //MD5(MD5(password)+salt) logininfo.setPassword(MD5Utils.formPassToDBPass(password, salt)); logininfo.setState(Constants.STATE_NORMAL); logininfo.setUserType(Constants.USERTYPE_NORMAL); logininfo.setRegisterDate(new Date()); logininfo.setLastLoginDate(new Date()); logininfo.setSalt(salt); this.loginInfoMapper.insert(logininfo); //初始化一个account Account account = Account.empty(logininfo.getId()); accountMapper.insert(account); //初始化一个Userinfo Userinfo userinfo = Userinfo.empty(logininfo.getId()); int result = this.userinfoMapper.insert(userinfo); } else { throw new RuntimeException("用户名已经存在!"); } } @Override public boolean checkUsername(String name, int userType) { return this.loginInfoMapper.getCountByNickname(name, userType) <= 0; } @Override public ResultGeekQ login(String name, String password, int userType, String ip) { ResultGeekQ resultGeekQ = ResultGeekQ.build(); try { IpLog log = new IpLog(name, new Date(), ip, userType, null); Logininfo logininfo = loginInfoMapper.getLoginInfoByNickname(name, Constants.USERTYPE_NORMAL); String salt = logininfo.getSalt(); Logininfo current = this.loginInfoMapper.login(name, MD5Utils.formPassToDBPass(password, salt), userType); if (current != null) { redisService.set("Login" + current.getNickname(), current); // RedisCacheStorageService.set("login"+current.getId().toString(),10000,current); log.setLoginInfoId(current.getId()); log.setLoginState(IpLog.LOGINSTATE_SUCCESS); } ipLogMapper.insert(log); resultGeekQ.setData(logininfo); } catch (Exception e) { logger.error("登录发生错误!", e); resultGeekQ.withError(ResultStatus.LOGIN_FIAL); } return resultGeekQ; } @Override public boolean hasAdmin() { return false; } @Override public void createDefaultAdmin() { } @Override public List> autoComplate(String word, int userType) { return null; } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/OrdersServiceImpl.java ================================================ package com.geekq.admin.service.impl; import com.geekq.admin.mapper.OrdersMapper; import com.geekq.admin.pojo.Orders; import com.geekq.admin.service.OrdersService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.UUID; @Service("ordersService") public class OrdersServiceImpl implements OrdersService { final static Logger log = LoggerFactory.getLogger(OrdersServiceImpl.class); @Autowired private OrdersMapper ordersMapper; @Override public Orders getOrder(String orderId) { return ordersMapper.selectByPrimaryKey(orderId); } @Override public boolean createOrder(String itemId) { // 创建订单 String oid = UUID.randomUUID().toString().replaceAll("-", ""); // Orders o = new Orders(); // o.setId(oid); // o.setOrderNum(oid); // o.setItemId(itemId); // ordersMapper.insert(o); log.info("订单创建成功"); return true; } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/RedisCache.java ================================================ package com.geekq.admin.service.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import java.io.Serializable; @Service public class RedisCache implements Serializable { /** * 日志记录 */ final static Logger LOG = LoggerFactory.getLogger(RedisCache.class); /** * redis 连接池 */ @Autowired private JedisPool pool; /*static { if (pool == null) { //读取相关的配置 ResourceBundle resourceBundle = ResourceBundle.getBundle("redis"); int maxActive = Integer.parseInt(resourceBundle.getString("redis.maxActive")); int maxIdle = Integer.parseInt(resourceBundle.getString("redis.maxIdle")); int maxWait = Integer.parseInt(resourceBundle.getString("redis.maxWait")); String host = resourceBundle.getString("redis.host"); int port = Integer.parseInt(resourceBundle.getString("redis.port")); String pass = resourceBundle.getString("redis.pass"); JedisPoolConfig config = new JedisPoolConfig(); //设置最大连接数 config.setMaxTotal(maxActive); //设置最大空闲数 config.setMaxIdle(maxIdle); //设置超时时间 config.setMaxWaitMillis(maxWait); //初始化连接池 pool = new JedisPool(config, host, port, 2000, pass); } }*/ /** * 获取jedis * * @return jedis */ public Jedis getResource() { Jedis jedis = null; try { jedis = pool.getResource(); } catch (Exception e) { LOG.info("can't get the redis resource"); } return jedis; } /** * 关闭连接 * * @param jedis j */ public void disconnect(Jedis jedis) { jedis.disconnect(); } /** * 将jedis 返还连接池 * * @param jedis j */ public void returnResource(Jedis jedis) { if (null != jedis) { try { pool.returnResource(jedis); } catch (Exception e) { LOG.info("can't return jedis to jedisPool"); } } } /** * 无法返还jedispool,释放jedis客户端对象 * * @param jedis j */ public void brokenResource(Jedis jedis) { if (jedis != null) { try { pool.returnBrokenResource(jedis); } catch (Exception e) { LOG.info("can't release jedis Object"); } } } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/RedisCacheStorageServiceImpl.java ================================================ package com.geekq.admin.service.impl; import com.alibaba.fastjson.JSON; import com.geekq.admin.entity.Logininfo; import com.geekq.admin.service.RedisCacheStorageService; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; @Service("redisCacheStorageServiceImpl") public class RedisCacheStorageServiceImpl implements RedisCacheStorageService { final static Logger LOG = LoggerFactory.getLogger(RedisCache.class); @Autowired private RedisCache redisCache; @SuppressWarnings("unchecked") public static T stringToBean(String str, Class clazz) { if (str == null || str.length() <= 0 || clazz == null) { return null; } if (clazz == int.class || clazz == Integer.class) { return (T) Integer.valueOf(str); } else if (clazz == String.class) { return (T) str; } else if (clazz == long.class || clazz == Long.class) { return (T) Long.valueOf(str); } else { return JSON.toJavaObject(JSON.parseObject(str), clazz); } } @Override public boolean set(String key, Object value) { Jedis jedis = null; // 将key 和value 转换成 json 对象 // String jKey = JSON.toJSONString(key); String jValue = JSON.toJSONString(value); // 操作是否成功 boolean isSucess = true; if (StringUtils.isEmpty(key)) { LOG.info("key is empty"); return false; } try { // 获取客户端对象 jedis = redisCache.getResource(); // 执行插入 jedis.set(key, jValue); } catch (Exception e) { LOG.info("client can't connect server"); isSucess = false; if (null != jedis) { // 释放jedis对象 redisCache.brokenResource(jedis); } return false; } finally { if (isSucess) { // 返还连接池 redisCache.returnResource(jedis); } } return true; } @Override public Logininfo get(String key) { Jedis jedis = null; try { jedis = redisCache.getResource(); //生成真正的key String str = jedis.get(key); Logininfo t = stringToBean(str, Logininfo.class); return t; } finally { redisCache.returnResource(jedis); } } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/SystemDictionaryServiceImpl.java ================================================ package com.geekq.admin.service.impl; import com.geekq.admin.entity.SystemDictionary; import com.geekq.admin.entity.SystemDictionaryItem; import com.geekq.admin.mapper.SystemDictionaryItemMapper; import com.geekq.admin.mapper.SystemDictionaryMapper; import com.geekq.admin.query.PageResult; import com.geekq.admin.query.SystemDictionaryQueryObject; import com.geekq.admin.service.ISystemDictionaryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service("iSystemDictionaryServiceImpl") public class SystemDictionaryServiceImpl implements ISystemDictionaryService { @Autowired private SystemDictionaryMapper systemDictionaryMapper; @Autowired private SystemDictionaryItemMapper systemDictionaryItemMapper; @Override public List listDics() { return systemDictionaryMapper.selectAll(); } @Override public PageResult queryDic(SystemDictionaryQueryObject qo) { int count = this.systemDictionaryMapper.queryForCount(qo); if (count > 0) { List list = this.systemDictionaryMapper.query(qo); return new PageResult(count, qo.getPageSize(), qo.getCurrentPage(), list); } return PageResult.empty(qo.getPageSize()); } @Override public void saveOrUpdate(SystemDictionary sd) { if (sd.getId() != null) { this.systemDictionaryMapper.updateByPrimaryKey(sd); } else { this.systemDictionaryMapper.insert(sd); } } @Override public PageResult queryDicItem(SystemDictionaryQueryObject qo) { int count = this.systemDictionaryItemMapper.queryForCount(qo); if (count > 0) { List list = this.systemDictionaryItemMapper .query(qo); return new PageResult(count, qo.getPageSize(), qo.getCurrentPage(), list); } return PageResult.empty(qo.getPageSize()); } @Override public void saveOrUpdateItem(SystemDictionaryItem item) { if (item.getId() != null) { this.systemDictionaryItemMapper.updateByPrimaryKey(item); } else { this.systemDictionaryItemMapper.insert(item); } } @Override public List queryBySn(String sn) { return this.systemDictionaryItemMapper.queryBySn(sn); } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/SystemDictionaryUtil.java ================================================ package com.geekq.admin.service.impl; import com.geekq.admin.entity.SystemDictionaryItem; import com.geekq.admin.service.ISystemDictionaryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; /** * 数据字典工具类 * * @author Administrator */ @Component public class SystemDictionaryUtil { @Autowired private ISystemDictionaryService systemDictionaryService; public List list(String sn) { return systemDictionaryService.queryBySn(sn); } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/service/impl/UserServiceImpl.java ================================================ package com.geekq.admin.service.impl; import com.geekq.admin.entity.Userinfo; import com.geekq.admin.mapper.UserinfoMapper; import com.geekq.admin.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("userServiceImpl") public class UserServiceImpl implements IUserService { @Autowired private UserinfoMapper userinfoMapper; /*@Autowired private ISendVerifyCodeService verifyCodeService;*/ /* @Value("${db.timeout}") private String salt; */ @Override public void update(Userinfo userinfo) { /* int ret = userinfoMapper.updateByPrimaryKey(userinfo,salt); if (ret <= 0) { throw new RuntimeException("乐观锁失败");*/ /* throw new RuntimeException("Userinfo对象:" + userinfo.getId() + " 乐观锁失败!");*/ } @Override public Userinfo get(Long id) { return null;/*userinfoMapper.selectByPrimaryKey(id,salt);*/ } @Override public boolean bindPhone(String phoneNumber, String verifyCode) { return false; } /*@Override public boolean bindPhone(String phoneNumber, String verifyCode) { boolean ret = verifyCodeService.verifyCode(phoneNumber, verifyCode); if (ret) { Userinfo ui = this.get(UserContext.getCurrent().getId()); ui.setPhoneNumber(phoneNumber); ui.addState(BitStatesUtils.OP_BIND_PHONE); this.update(ui); return true; } return false; }*/ @Override public void updateBasicInfo(Userinfo userinfo) { /* Userinfo current = this.userinfoMapper.selectByPrimaryKey(UserContext .getCurrent().getId(),salt);*/ /* current.setEducationBackground(userinfo.getEducationBackground()); current.setHouseCondition(userinfo.getHouseCondition()); current.setIncomeGrade(userinfo.getIncomeGrade()); current.setKidCount(userinfo.getKidCount()); current.setMarriage(userinfo.getMarriage()); if (!current.getBaseInfo()) { current.addState(BitStatesUtils.OP_BASE_INFO); } this.update(current);*/ } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/java/com/geekq/admin/utils/UserContext.java ================================================ package com.geekq.admin.utils; import com.geekq.admin.entity.Logininfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextListener; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class UserContext { public static final String LOGIN_IN_SESSION = "logininfo"; public static final String VERIFYCODE_IN_SESSION = "VERIFYCODE_IN_SESSION"; private static ThreadLocal userHolder = new ThreadLocal(); @Autowired private HttpSession session; @Autowired private HttpServletRequest request; /* @Autowired private RedisService redisService;*/ private static HttpServletRequest getRequest() { return ((ServletRequestAttributes) RequestContextHolder .getRequestAttributes()).getRequest(); } public static void removeUser() { userHolder.remove(); } /* public static void putLogininfo(Logininfo user) { userHolder.set(user); } public static Logininfo getCurrent() { return userHolder.get(); }*/ public static void putLogininfo(Logininfo logininfo) { HttpServletRequest a = ((ServletRequestAttributes) RequestContextHolder .getRequestAttributes()).getRequest(); HttpSession b = a.getSession(); b.setAttribute(LOGIN_IN_SESSION, logininfo); } public static Logininfo getCurrent() { return (Logininfo) getRequest().getSession().getAttribute( LOGIN_IN_SESSION); } @Bean public RequestContextListener requestContextListener() { return new RequestContextListener(); } // public static void putVerifyCode(VerifyCode code) { // getRequest().getSession().setAttribute(VERIFYCODE_IN_SESSION, code); // } // // public static VerifyCode getVerifyCode() { // return (VerifyCode) getRequest().getSession().getAttribute( // VERIFYCODE_IN_SESSION); // } } ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/dubbo/dubbo.xsd ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/log4j.properties ================================================ log4j.rootLogger=INFO,console #INFO,console,dailyFile log4j.logger.com.geekq.mapper=INFO log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.encoding=UTF-8 log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%l] - [%p] %m%n ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/mybatis/SqlMapConfig.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/resource/db.properties ================================================ jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/miaosha2?characterEncoding=utf-8 jdbc.username=root jdbc.password=nihaoma db.properties ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/resource/redis.properties ================================================ #访问地址 redis.host=39.107.245.253 redis.port=6379 redis.pass=youxin11 redis.maxIdle=25 redis.maxActive=100 redis.maxWait=1000 redis.testOnBorrow=false redis.testOnReturn=false ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/spring/applicationContext-dao.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/spring/applicationContext-dubbo-provider.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/spring/applicationContext-redis.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/spring/applicationContext-service.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/spring/applicationContext-transaction.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/resources/spring/spring-context.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-service/src/main/webapp/WEB-INF/web.xml ================================================ imooc-dubbo-order-service contextConfigLocation classpath:spring/applicationContext-*.xml org.springframework.web.context.ContextLoaderListener org.springframework.web.context.request.RequestContextListener ================================================ FILE: miaosha-admin/miaosha-admin-web/pom.xml ================================================ 4.0.0 com.geekq miaosha-admin ${revision} miaosha-admin-web war org.freemarker freemarker com.alibaba dubbo org.apache.zookeeper zookeeper com.github.sgroschupf zkclient org.apache.curator curator-framework org.apache.curator curator-recipes org.springframework spring-context org.springframework spring-beans org.springframework spring-webmvc org.springframework spring-jdbc org.springframework spring-aspects org.springframework spring-context-support com.geekq miaosha-admin-service javax.servlet javax.servlet-api ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/controller/BaseController.java ================================================ package com.geekq.web.controller; /** * @author 邱润泽 */ abstract public class BaseController { } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/controller/LoginController.java ================================================ package com.geekq.web.controller; import com.geekq.admin.entity.Logininfo; import com.geekq.admin.service.ILogininfoService; import com.geekq.admin.service.RedisCacheStorageService; import com.geekq.common.enums.Constants; import com.geekq.common.utils.resultbean.ResultGeekQ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author 邱润泽 * 登录模块 */ @Controller public class LoginController extends BaseController { private static Logger logger = LoggerFactory.getLogger(LoginController.class); @Autowired private ILogininfoService iLogininfoService; @Autowired private RedisCacheStorageService redisCacheStorageService; @RequestMapping("/login") @ResponseBody public ResultGeekQ dologin(HttpServletResponse response, HttpServletRequest request, String username, String password) { ResultGeekQ result = ResultGeekQ.build(); ResultGeekQ login = this.iLogininfoService.login(username, password, Constants.USERTYPE_NORMAL, request.getRemoteAddr()); result.setData(login.getData()); if (!ResultGeekQ.isSuccess(login)) { result.withError(login.getCode(), login.getMessage()); } return result; } } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/controller/PayController.java ================================================ package com.geekq.web.controller; import com.geekq.web.interceptor.RequiredLogin; import com.geekq.web.service.CulsterService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @Description: 订购商品controller */ @Controller public class PayController { @Autowired private CulsterService buyService; @RequiredLogin @RequestMapping("/index") public String index() { return "login"; } } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/controller/PersonController.java ================================================ package com.geekq.web.controller; import com.geekq.admin.entity.Logininfo; import com.geekq.admin.service.IAccountService; import com.geekq.admin.service.IUserService; import com.geekq.admin.service.RedisCacheStorageService; import com.geekq.web.interceptor.RequiredLogin; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller public class PersonController extends BaseController { @Autowired private IUserService userinfoService; @Autowired private IAccountService accountService; @Autowired private RedisCacheStorageService redisService; @RequiredLogin @RequestMapping("/personal") public String personal(Model model, HttpServletRequest request) { //从中拿到 用户信息对象 String username = request.getParameter("username"); Logininfo info = redisService.get("Login" + username); model.addAttribute("userinfo", userinfoService.get(info.getId())); model.addAttribute("account", accountService.get(info.getId())); model.addAttribute("logininfo", info); return "personal"; } } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/controller/RegisterController.java ================================================ package com.geekq.web.controller; import com.geekq.admin.service.ILogininfoService; import com.geekq.common.enums.Constants; import com.geekq.common.enums.ResultStatus; import com.geekq.common.utils.resultbean.ResultGeekQ; import com.geekq.common.utils.resultbean.ResultJSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @author 邱润泽 */ @Controller public class RegisterController extends BaseController { private static final Logger logger = LoggerFactory.getLogger(RegisterController.class); @Autowired private ILogininfoService logininfoService; @RequestMapping("/register") @ResponseBody public ResultJSON register(String username, String password) { ResultJSON json = new ResultJSON(); try { this.logininfoService.register(username, password); json.setSuccess(true); } catch (RuntimeException e) { logger.error("注册失败", e); json.setMsg("注册失败,请联系相关人员!"); } return json; } @RequestMapping("/checkUsername") @ResponseBody public ResultGeekQ checkUsername(String username) { ResultGeekQ result = ResultGeekQ.build(); try { result.setData(this.logininfoService.checkUsername(username, Constants.USERTYPE_NORMAL)); } catch (RuntimeException e) { logger.error("检查是否存在该用户名!", e); result.withError(ResultStatus.SYSTEM_ERROR); } return result; } } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/interceptor/AddGlobalUtilInterceptor.java ================================================ package com.geekq.web.interceptor; import com.geekq.admin.service.impl.SystemDictionaryUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AddGlobalUtilInterceptor extends HandlerInterceptorAdapter { @Autowired private SystemDictionaryUtil systemDicUtil; @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (modelAndView != null) { modelAndView.addObject("_DicUtil", systemDicUtil); } super.postHandle(request, response, handler, modelAndView); } } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/interceptor/LoginInterceptor.java ================================================ package com.geekq.web.interceptor; import com.geekq.admin.entity.Logininfo; import com.geekq.admin.service.RedisCacheStorageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginInterceptor extends HandlerInterceptorAdapter { @Autowired private RedisCacheStorageService redisService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod) { HandlerMethod hm = (HandlerMethod) handler; RequiredLogin rl = hm.getMethodAnnotation(RequiredLogin.class); System.out.println(request.getParameter("username")); String username = request.getParameter("username"); if (rl != null) { Logininfo current = redisService.get("Login" + username); if (current == null) { response.sendRedirect("/login.html"); return false; } } } return super.preHandle(request, response, handler); } } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/interceptor/RequiredLogin.java ================================================ package com.geekq.web.interceptor; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequiredLogin { } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/service/CulsterService.java ================================================ package com.geekq.web.service; public interface CulsterService { /** * @Description: 购买商品 */ public void doBuyItem(String itemId); public boolean displayBuy(String itemId); } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/java/com/geekq/web/service/impl/CulsterServiceImpl.java ================================================ package com.geekq.web.service.impl; import com.geekq.admin.service.OrdersService; import com.geekq.web.service.CulsterService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service("buyService") public class CulsterServiceImpl implements CulsterService { final static Logger log = LoggerFactory.getLogger(CulsterServiceImpl.class); // @Autowired // private ItemsService itemService; @Autowired private OrdersService ordersService; @Override public void doBuyItem(String itemId) { // 减少库存 // itemService.displayReduceCounts(itemId, 1); // 创建订单 ordersService.createOrder(itemId); } @Override public boolean displayBuy(String itemId) { int buyCounts = 5; // // 1. 判断库存 // int stockCounts = itemService.getItemCounts(itemId); // if (stockCounts < buyCounts) { // log.info("库存剩余{}件,用户需求量{}件,库存不足,订单创建失败...", // stockCounts, buyCounts); // return false; // } // // // 2. 创建订单 boolean isOrderCreated = ordersService.createOrder(itemId); // // // 3. 创建订单成功后,扣除库存 // if (isOrderCreated) { // log.info("订单创建成功..."); // itemService.displayReduceCounts(itemId, buyCounts); // } else { // log.info("订单创建失败..."); // return false; // } return true; } } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/resources/log4j.properties ================================================ log4j.rootLogger=INFO,console #INFO,console,dailyFile log4j.logger.com.geekq.mapper=INFO log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.encoding=UTF-8 log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%l] - [%p] %m%n ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/resources/spring/applicationContext-dubbo-consumer.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/resources/spring/applicationContext-service.xml ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/resources/spring/springmvc.xml ================================================ number_format = 0.## datetime_format = yyyy-MM-dd HH:mm:ss ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/bankInfo.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl"/> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
<#assign currentMenu="bankInfo"/> <#include "common/leftmenu-tpl.ftl" />
绑定银行卡
<#if userinfo.realAuth>

为保护您账户安全,绑定银行卡之后,不能自己修改,请认真填写!

${userinfo.realName}

<#else>

请先完成实名认证之后,才能进行银行卡绑定;

<#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/bankInfo_result.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
<#assign currentMenu = "bankInfo" /> <#include "common/leftmenu-tpl.ftl" />
绑定银行卡

你已经绑定了银行卡


开户名: ${userinfo.anonymousRealName} 开户行:${bankInfo.bankType.bankName}
支行名称: ${bankInfo.bankName} 银行账号:${bankInfo.anonymousAccountNumber}
<#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/bidRequest_list.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
<#assign currentMenu="bidRequest" /> <#include "common/leftmenu-tpl.ftl" />
借款项目
<#list pageResult.result as data>
标题 发标时间 借款金额(元) 期限 利率 总利息 状态
${data.title} ${(data.publishTime?string("yyyy-MM-dd HH:mm:SS"))!'未发布'} ${data.bidRequestAmount} ${data.monthes2Return}月 ${data.currentRate}% ${data.totalRewardAmount} ${data.bidRequestStateDisplay}
    <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/bid_list.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
    <#assign currentMenu="bid" /> <#include "common/leftmenu-tpl.ftl" />
    投资项目
    <#list pageResult.result as data>
    投资借款 投资时间 投资金额(元) 利息 状态
    ${data.bidRequestTitle} ${data.bidTime?string("yyyy-MM-dd HH:mm:SS")} ${data.availableAmount} 元 ${data.actualRate} % ${data.bidRequestStateDisplay}
      <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/borrow.ftl ================================================ 蓝源Eloan-P2P平台->我要借款 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="borrow" /> <#include "common/navbar-tpl.ftl" />
      信用贷

      认证后可借金额 ¥ ${account.remainBorrowLimit}

      申请条件

      仅限广州地区

      <#if userinfo.baseInfo && userinfo.realAuth && (userinfo.authScore >= creditBorrowScore) && userinfo.vedioAuth> 申请贷款 <#else> 申请贷款
      车易贷

      认证后可借金额 ¥ 10,000.00

      申请条件

      仅限广州地区

      • 填写基本资料
      • 身份认证
      • 材料认证分数达到30分
      • 提交车辆抵押相关资料
      • 视频认证
      申请贷款
      房易贷

      可借金额 ¥ 10,0000.00

      申请条件

      仅限广州地区

      • 填写基本资料
      • 身份认证
      • 材料认证分数达到50分
      • 提交房屋抵押相关资料
      • 视频认证
      申请贷款
      <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/borrow_apply.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="borrow" /> <#include "common/navbar-tpl.ftl" />

      信用借款

      可借金额:${account.remainBorrowLimit}

      %

      相关费用

      利息 --

      奖金 --

      管理费 --

      <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/borrow_apply_result.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="borrow" /> <#include "common/navbar-tpl.ftl" />

      借款提示

      你目前有标正在申请的流程当中,不能再次发标;或者你恶意的进入了发标流程,请按照正常流程完成发标前的相关资料提交,谢谢!

      <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/borrow_info.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav = "invest" /> <#include "common/navbar-tpl.ftl" />
      借款人

      ${bidRequest.createUser.username}


      籍贯: 四川 - 成都
      认证信息:

      ${bidRequest.title}借款

      借款金额 ${bidRequest.bidRequestAmount} 年化利率 ${bidRequest.currentRate}%
      借款期限 ${bidRequest.monthes2Return}月 总可得利息 ${bidRequest.totalRewardAmount}
      还款方式 ${bidRequest.returnTypeDisplay} 最小投标 ${bidRequest.minBidAmount}
      风控意见 ${bidRequest.note}
      剩余时间
      投标总数 ${bidRequest.bidCount}
      还需金额 ${bidRequest.remainAmount} 元
      投标进度
      <#if bidRequest.bidRequestState==1> <#if self>
      投标中 <#elseif account?? && !self>
      可用余额 ${account.usableAmount}
      已投
      还需要 ${bidRequest.remainAmount}
      <#else>
      登录投标 <#if bidRequest.bidRequestState==4 || bidRequest.bidRequestState==5>

      满标审核中

      <#if bidRequest.bidRequestState==7>

      还款中

      <#if bidRequest.bidRequestState==8>

      已还清

      借款人信息
      出生时间 ${(realAuth.birthDate)!""} 借款额度 ${bidRequest.bidRequestAmount} 性别 ${realAuth.sexDisplay} 住房条件 ${userInfo.houseCondition.title}
      文化程度 ${userInfo.educationBackground.title} 每月收入 ${userInfo.incomeGrade.title} 婚姻情况 ${userInfo.marriage.title} 子女情况 ${userInfo.kidCount.title}
      材料信息
      <#list userFiles as file>
      材料类型 材料数量
      ${file.fileType.title} 1
      还款情况
      还款状态 最近一周 最近1月 最近6月 6个月前 总计[?]
      提前还款 0 0 0 0 0
      准时还款 0 0 0 0 0
      逾期已还 0 0 0 0 0
      逾期未还 0 0 0 0 0
      投标记录
      <#if bidRequest.bids?size > 0> <#list bidRequest.bids as bid> <#else>
      投标人 年利率 有效金额(¥) 投标时间 类型
      ${bid.bidUser.username} ${bid.actualRate}% ${bid.availableAmount} ${bid.bidTime?string("yyyy-MM-dd HH:mm:ss")} 手动投标

      暂时没有投标数据

      <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/checkmail_result.ftl ================================================ 蓝源Eloan-P2P平台->邮件激活

      <#if success> 您的邮件已经成功激活,请登录系统查看! <#else> 您的邮件激活失败,失败原因是:${msg}!

      专注于高级Java开发工程师的培养

      版权所有: 2015广州小码哥教育科技有限公司

      地  址: 广州市天河区棠下荷光三横路盛达商务园D座5楼

      电  话: 020-29007520   邮箱: service@520it.com

      ICP备案 :粤ICP备字1504547

      穗公网安备:44010650010086

      ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/common/footer-tpl.ftl ================================================

      专注于高级Java开发工程师的培养

      版权所有: 2015广州小码哥教育科技有限公司

      地  址: 广州市天河区棠下荷光三横路盛达商务园D座5楼

      电  话: 020-29007520   邮箱: service@520it.com

      ICP备案 :粤ICP备字1504547

      穗公网安备:44010650010086

      ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/common/head-tpl.ftl ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/common/leftmenu-tpl.ftl ================================================ <#if currentMenu??> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/common/links-tpl.ftl ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/common/loadSystemDictionary-macro.ftl ================================================ <#macro loadDictionary sn> <#assign itemList = _DicUtil.list(sn)/> <#list itemList as item> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/common/navbar-tpl.ftl ================================================ <#if currentNav??> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/invest.ftl ================================================ 蓝源Eloan-P2P平台->我要借款 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="invest" /> <#include "common/navbar-tpl.ftl" />

      投资列表

      标的状态
      借款人 借款标题 年利率 金额 还款方式 进度 操作
        <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/invest_list.ftl ================================================ <#if pageResult.result?size > 0 > <#list pageResult.result as data> ${data.createUser.username } ${data.title} ${data.currentRate}% ${data.bidRequestAmount} ${data.returnTypeDisplay}
        ${data.persent} %
        查看 <#else>

        目前没有符合要求的标

        ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/iplog_list.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
        <#assign currentMenu="iplog" /> <#include "common/leftmenu-tpl.ftl" />
        登录日志
        <#list pageResult.result as data>
        用户 登录时间 登录ip 登录状态
        ${data.username} ${data.loginTime?string("yyyy-MM-dd HH:mm:SS")} ${data.ip} ${data.displayState}
          <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/main.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav = "index" /> <#include "common/navbar-tpl.ftl" />
          投资理财
          稳定投资、高收益、短期限,易融贷先行赔付,保障投资人权益。
          投资理财
          稳定投资、高收益、短期限,易融贷先行赔付,保障投资人权益。
          投资理财
          稳定投资、高收益、短期限,易融贷先行赔付,保障投资人权益。
          进行中借款
          <#if bidRequests?size > 0 > <#list bidRequests as data> <#else>
          借款人 借款标题 年利率 金额 还款方式 借款期限 进度 操作
          ${data.createUser.username } ${data.title} ${data.currentRate}% ${data.bidRequestAmount} ${data.returnTypeDisplay} ${data.monthes2Return}月
          ${data.persent} %
          查看

          目前暂时没有进行中的借款

          <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/moneyWithdraw_apply.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#if !haveProcessing && bankInfo??> <#include "common/head-tpl.ftl"/> <#assign currentNav="withdraw" /> <#include "common/navbar-tpl.ftl" />
          <#assign currentMenu="moneyWithdraw"/> <#include "common/leftmenu-tpl.ftl" />

          账户提现

          1. 本平台工作日会处理当天 17:00 之前的提款申请。

          2. 为了确保银行转账成功,请您确认银行账号信息的 正确性。

          3. 单笔提现范围-普通用户500.00 元 ~ 500000.00 元。

          4. 单笔提现范围-VIP用户500.00 元 ~ 500000.00 元。

          5. 目前提现服务费:1万元(含) 之内:2.00 元/笔;1万元(以上) :5.00 元/笔。

          6. 为避免信用卡套现,故充值15日内未投资提现按提现金额的0.4%收取提现费用。

          7. 本次可提现 = 可用余额 - 净值保证金 - 不可提现金额 + 投标冻结 - 最高服务费 - 返还体验金

          <#if !haveProcessing>
          可提现金额:${account.usableAmount} 元
          冻结金额:${account.freezedAmount} 元
          <#if haveProcessing>

          您有提现申请正在处理中,请完这个提现申请完成后再次申请;

          <#elseif bankInfo??>
          <#else>

          请先绑定银行卡,再申请提现;

          <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/personal.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
          <#assign currentMenu="account" /> <#include "common/leftmenu-tpl.ftl" />
          <#if !userinfo.isBindPhone> <#if !userinfo.isBindEmail> <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/realAuth.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl"/> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
          <#assign currentMenu="realAuth"/> <#include "common/leftmenu-tpl.ftl" />
          实名认证

          为保护您账户安全,实名认证成功之后不能修改信息,请认真填写!

          ${logininfo.username }

          请点击“选择图片”,选择证件的正反两面照片。

          查看样板
          <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/realAuth_result.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
          <#assign currentMenu = "realAuth" /> <#include "common/leftmenu-tpl.ftl" />
          <#if (auditing)??>

          实名认证

          实名认证资料已经提交,等待业务员审核,请耐心等待;如果急需审核请联系客服;

          <#else>
          实名认证

          你已经通过实名认证


          真实姓名: ${realAuth.realname} 性别:${realAuth.sexDisplay}
          证件号码: ${realAuth.idNumber} 出生日期:${(realAuth.birthDate)!''}
          <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/recharge.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" />

          账户充值

          1. 由于银行系统的限制,充值功能建议使用 IE 内核(IE8及以上)的浏览器。

          2. 请注意:为打击信用卡套现行为,充值资金必须经过投资回款后方能允许提现。

          <#list banks as bank>
          银行名称 开户人姓名 银行帐号 开户行支行名称
          ${bank.accountname} ${bank.banknumber} ${bank.bankforkname}

          第一步:

          请选择往以上一个账号汇款或转账您所要充值的金额(若您是跨行转账,推荐选择建行)。注:请保存您的交易记录信息。

          第二步:

          款或转账成功后,再选择你所汇款或转账的账号,并填写以下完整的信息后,提交您的线下充值申请。我们将会在下个工作日核对您的申请。

          系统暂不支持,请采用线下充值

          <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/recharge_list.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
          <#assign currentMenu="recharge" /> <#include "common/leftmenu-tpl.ftl" />
          充值明细 账户充值
          <#list pageResult.result as data>
          平台账号 交易号 充值时间 充值金额 充值状态
          ${data.tradeCode} ${data.tradeTime?string("yyyy-MM-dd")} ${data.amount} 元 ${data.stateDisplay}
            <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/returnmoney_list.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
            <#assign currentMenu="recharge" /> <#include "common/leftmenu-tpl.ftl" />
            还款明细 账户充值
            <#list pageResult.listData as data>
            借款 还款金额 还款本金 还款利息 还款期数 还款期限 还款状态
            ${data.bidRequestTitle} ${data.totalAmount}元 ${data.principal}元 ${data.interest}元 ${data.monthIndex}期 ${data.deadLine?string("yyyy-MM-dd")} <#if data.state=0> 立刻还款 <#else> ${data.stateDisplay}
              <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/userFiles.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/loadSystemDictionary-macro.ftl" /> <#include "common/head-tpl.ftl"/> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
              <#assign currentMenu="userFile"/> <#include "common/leftmenu-tpl.ftl" />
              用户认证文件信息
              <#list userFiles as file>

              ${file.fileType.title}

              得分:${file.score}   状态:${file.stateDisplay}

              <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/userFiles_commit.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/loadSystemDictionary-macro.ftl" /> <#include "common/head-tpl.ftl"/> <#assign currentNav="account" /> <#include "common/navbar-tpl.ftl" />
              <#assign currentMenu="userFile"/> <#include "common/leftmenu-tpl.ftl" />
              用户认证文件信息
              <#list userFiles as file>

              <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/views/userInfo.ftl ================================================ 蓝源Eloan-P2P平台 <#include "common/links-tpl.ftl" /> <#include "common/loadSystemDictionary-macro.ftl" /> <#include "common/head-tpl.ftl" /> <#assign currentNav="account"/> <#include "common/navbar-tpl.ftl" />
              <#assign currentMenu="userInfo" /> <#include "common/leftmenu-tpl.ftl" />
              个人资料

              ${logininfo.username}

              <#if (userinfo.realAuth)> ${userinfo.anonymousRealName} <#else> 未认证 [马上认证]

              <#if (userinfo.realAuth)> ${userinfo.idNumber} <#else> 未认证 [马上认证]

              <#include "common/footer-tpl.ftl" /> ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/WEB-INF/web.xml ================================================ springMVC org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:/spring/springmvc.xml 1 springMVC *.do characterEncoding org.springframework.web.filter.CharacterEncodingFilter encoding utf-8 characterEncoding *.do contextConfigLocation classpath:spring/applicationContext-*.xml org.springframework.web.context.ContextLoaderListener org.springframework.web.context.request.RequestContextListener ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/bootstrap.html ================================================ Bootstrap 101 Template

              你好,世界!

              你好,世界2!

              货品编号 货品名称 品牌 默认销售价 默认成本价
              货品编号 货品名称 品牌 默认销售价 默认成本价
              货品编号 货品名称 品牌 默认销售价 默认成本价
              货品编号 货品名称 品牌 默认销售价 默认成本价
              货品编号 货品名称 品牌 默认销售价 默认成本价
              点我
              60%
              ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/borrow.html ================================================ 蓝源Eloan-P2P平台->我要借款
              信用贷

              认证后可借金额 ¥ 2,000.00

              申请条件

              仅限广州地区

              • 填写基本资料
              • 身份认证
              • 材料认证分数达到30分
              • 视频认证
              登陆后申请
              车易贷

              认证后可借金额 ¥ 10,000.00

              申请条件

              仅限广州地区

              • 填写基本资料
              • 身份认证
              • 材料认证分数达到30分
              • 提交车辆抵押相关资料
              • 视频认证
              登陆后申请
              房易贷

              可借金额 ¥ 10,0000.00

              申请条件

              仅限广州地区

              • 填写基本资料
              • 身份认证
              • 材料认证分数达到50分
              • 提交房屋抵押相关资料
              • 视频认证
              登陆后申请

              专注于高级Java开发工程师的培养

              版权所有: 2015广州小码哥教育科技有限公司

              地  址: 广州市天河区棠下荷光三横路盛达商务园D座5楼

              电  话: 020-29007520   邮箱: service@520it.com

              ICP备案 :粤ICP备字1504547

              穗公网安备:44010650010086

              ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/css/account.css ================================================ #menu>li.active { background: none; border: 1px solid #ddd; } #menu>li.list-group-item { padding: 0px; } #menu>li>a { outline: none; display: block; padding: 10px 15px; background: #F5F5F5; text-decoration: none; } #menu>li:first-child>a { border-top-left-radius: 4px; border-top-right-radius: 4px; } #menu>li.active>a { background: #337ab7; color: #FFFFFF; border-color: #337ab7; } #menu>li>ul { border-top: 1px solid #ddd; padding-left:0px; list-style: none; } #menu>li>ul>li { height: 40px; padding-left:40px; line-height: 40px; } #menu>li>ul>li.active{ background-color: #337ab7; } #menu>li>ul>li.active a{ color: #fff; } .el-account .el-account-info { border-bottom: 1px solid #ddd; padding-bottom: 26px; margin-bottom: 20px; } .el-account .el-account-info .el-head-img { border: 1px solid #ddd; padding: 10px; float: left;; } .account-info{ margin:26px; } .top-margin{ margin-top: 30px; border-top: 1px solid #ddd; } .el-account .el-account-info .el-head { margin-top: 5px; margin-left: 15px; } .el-account .el-accoun-auth { padding: 40px 0px 0px 10px; } .el-account .el-accoun-auth h5 { font-weight: bold; padding: 0px; margin: 0px 0px 10px 0px; } .el-account .el-accoun-auth .info { font-size: 13px; margin-top: 8px; } .el-account .el-accoun-auth .el-accoun-auth-left { float: left; } .el-account .el-accoun-auth .el-accoun-auth-right { float: left; margin-left: 10px; } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/css/bank.css ================================================ .bank { background: url("../images/bank_list.png") no-repeat scroll 0 0 transparent; cursor: pointer; display: block; height: 32px; text-indent: -9999px; vertical-align: 0; width: 140px; } .bank_1 { background-position: 0 0; } .bank_2 { background-position: 0 -35px; } .bank_3 { background-position: 0 -70px; } .bank_4 { background-position: 0 -105px; } .bank_5 { background-position: 0 -140px; } .bank_6 { background-position: 0 -175px; } .bank_7 { background-position: 0 -210px; } .bank_8 { background-position: 0 -245px; } .bank_9 { background-position: 0 -280px; } .bank_10 { background-position: 0 -315px; } .bank_11 { background-position: 0 -350px; } .bank_12 { background-position: 0 -385px; } .bank_13 { background-position: 0 -420px; } .bank_14 { background-position: 0 -455px; } .bank_15 { background-position: 0 -490px; } .bank_16 { background-position: 0 -525px; } .bank_17 { background-position: 0 -700px; } .bank_18 { background-position: 0 -737px; } .bank_19 { background-position: 0 -594px; } .bank_20 { background-position: 0 -631px; } .bank_21 { background-position: 0 -560px; } .bank_28 { background-position: 0 -665px; } .bank_33 { background-position: 0 -770px; } .bank_34 { background-position: 0 -805px; } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/css/core.css ================================================ body { font: 14px/1.5 "Verdana", "微软雅黑", YaHei, tahoma, arial, Hiragino Sans GB, "宋体" } .el-header { background-color: #333333; } .el-header .navbar-nav>li { margin-left: 5px; margin-right: 5px; } .el-header .navbar-nav>li>a { padding-top: 10px; padding-bottom: 10px; color: #fff; } .el-header .navbar-nav>li>a:HOVER { background: transparent; color: #00a7ff; text-decoration: underline; } .el-header .navbar-nav>li>.el-current-user, .el-header .navbar-nav>li>.el-current-user:HOVER { color: #00a7ff; font-weight: bold; text-decoration: none; } .nav .open>a.el-current-user, .nav .open>a.el-current-user:hover { background: transparent; } .el-header .nav>li>a:FOCUS { background: transparent; } .el-navbar { margin-bottom: 5px; } .el-navbar .navbar-header { padding-top: 25px; padding-bottom: 10px; margin-right: 20px; } .el-navbar .navbar-nav>li>a { padding-top: 0px; padding-bottom: 0px; min-width: 80px; text-align: center; line-height: 80px; font-size: 16px; } .el-navbar .navbar-nav>li>a:HOVER { background: none repeat scroll 0 0 #f0f0f0; color: #09d; } /* banner广告 */ .el-banner { margin: 8px auto; width: 1328px; } /* p2p项目特色 */ .el-feature { overflow: hidden; height: 80px; margin-top: 40px; } .el-feature>dl { padding-left: 80px; float: left; width: 33%; } .el-feature .el-feature-item01 { background: url("../images/feature01.png") no-repeat; } .el-feature .el-feature-item02 { background: url("../images/feature02.png") no-repeat; } .el-feature .el-feature-item03 { background: url("../images/feature03.png") no-repeat; } .el-feature>dl>dt { font-size: 18px; margin-bottom: 10px; } .el-feature>dl>dd { color: #999; } /* footer网页底部 */ .el-footer { background-color: #f8f8f8; margin: 20px 0px 20px 0px; padding-top: 30px; } .el-footer img { max-width: 100%; } /* override bootstrap */ .el-page-title { font-weight: bold; font-size: 20px; margin-left: 20px; color: #337ab7; } /*自定义panel组件*/ .el-panel { box-shadow: none; } .el-panel .panel-title { font-size: 24px; color: #2e8ece; font-weight: bold; overflow: hidden; border-bottom: 1px solid #e8e8e8; margin: 60px 0px 16px; } .el-panel .panel-title span { border-bottom: 3px solid; } .el-table thead th { color: #999999; } .el-table tbody tr td { font-size: 16px; vertical-align: middle; } /*新闻列表*/ .el-new-list {} .el-new-list ul { padding: 0px;; } .el-new-list ul li { list-style-type: none; overflow: hidden; line-height: 38px; font-size: 14px; border-bottom: 1px dotted #eee; } .el-new-list ul li a { color: #555; overflow: hidden; } .el-new-list ul li a:hover { background: none repeat scroll 0 0 #f5f5f5; color: #09d; } .el-tip-info{ padding:20px; background-color: #F4F8FA; border-left: 2px solid #0099DD; margin-bottom: 20px; } .el-tip-info h3{ color:#09d; } .container-foot-2 { background-color: #000; color: #ffffff; height: 209px; margin: 0 auto; width: 100%; overflow: hidden; } .container-foot-2 .context { margin: 50px auto 0; width: 950px; } .container-foot-2 .context .left { float: left; width: 425px; } .container-foot-2 .context .right { float: right; width: 410px; } .container-foot-2 .context .right img { width: 200px; } .container-foot-2 p { color: #fff; font: 14px/1.5 "Verdana","微软雅黑",YaHei,tahoma,arial,Hiragino Sans GB,"宋体"; margin-top: 5px; text-align: left; } /*借款说明*/ .el-borrow{ margin: 60px auto; } .el-borrow-item{ float: left; margin-bottom: 40px; } .el-borrow-item .el-borrow-item-title{ font-size: 24px; background-color: #ec7e20; font-weight:300; line-height: 48px; padding-left: 20px; color: #FFFFFF; } .el-borrow-item .el-borrow-item-content{ background-color: #f9f9f9; padding: 14px; font-size: 16px; min-height: 300px; } .el-borrow-item .el-borrow-item-content a{ font-size: 13px; } .el-borrow-item .el-borrow-item-content .help-block{ font-size: 13px; } .el-borrow-item .el-borrow-item-content ul{ margin-top:10px; padding-left: 10px; } .el-borrow-item .el-borrow-item-content ul li{ color:#555; font-size:14px; list-style:none; padding-left:20px; margin-top:5px; background:url("/images/sequare.png") left center no-repeat ; } .el-borrow-item .el-borrow-item-content .el-borrow-apply{ border-radius: 20px; background: #00a8ff; color: #fff; display: block; margin: 0px auto; width: 100px; height: 30px; line-height: 30px; text-align: center; position: absolute; top: 300px; left: 140px; } .el-borrow-item .el-borrow-item-content .el-borrow-apply:HOVER{ background: #008fd9; text-decoration:none; } .el-bank{ display: block; width: 150px; height: 30px; background: url(/images/bank_list.png) no-repeat; } .bank_1 {/*工商银行*/ background-position: 0 0; } .bank_2 {/*农业银行*/ background-position: 0 -35px; } .bank_3 {/*建设银行*/ background-position: 0 -70px; } .bank_6 {/*交通银行*/ background-position: 0 -175px; } .bank_7 {/*中国银行*/ background-position: 0 -210px; } .bank_19 {/*中国邮政银行*/ background-position: 0 -594px; } ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/index.html ================================================ ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/js/My97DatePicker/My97DatePicker.htm ================================================ My97DatePicker ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/js/My97DatePicker/WdatePicker.js ================================================ /* * My97 DatePicker 4.6 Prerelease * SITE: http://dp.my97.net * BLOG: http://my97.cnblogs.com * MAIL: smallcarrot@163.com */ var $dp,WdatePicker;(function(){var _={ $wdate:true, $dpPath:"", $crossFrame:true, doubleCalendar:false, position:{}, lang:"auto", skin:"default", dateFmt:"yyyy-MM-dd", realDateFmt:"yyyy-MM-dd", realTimeFmt:"HH:mm:ss", realFullFmt:"%Date %Time", minDate:"1900-01-01 00:00:00", maxDate:"2099-12-31 23:59:59", startDate:"", alwaysUseStartDate:false, yearOffset:1911, firstDayOfWeek:0, isShowWeek:false, highLineWeekDay:true, isShowClear:true, isShowToday:true, isShowOthers:true, readOnly:false, errDealMode:0, autoPickDate:null, qsEnabled:true, specialDates:null,specialDays:null,disabledDates:null,disabledDays:null,opposite:false,onpicking:null,onpicked:null,onclearing:null,oncleared:null,ychanging:null,ychanged:null,Mchanging:null,Mchanged:null,dchanging:null,dchanged:null,Hchanging:null,Hchanged:null,mchanging:null,mchanged:null,schanging:null,schanged:null,eCont:null,vel:null,errMsg:"",quickSel:[],has:{}};WdatePicker=U;var X=window,O="document",J="documentElement",C="getElementsByTagName",V,A,T,I,b;switch(navigator.appName){case"Microsoft Internet Explorer":T=true;break;case"Opera":b=true;break;default:I=true;break}A=L();if(_.$wdate)M(A+"skin/WdatePicker.css");V=X;if(_.$crossFrame){try{while(V.parent[O]!=V[O]&&V.parent[O][C]("frameset").length==0)V=V.parent}catch(P){}}if(!V.$dp)V.$dp={ff:I,ie:T,opera:b,el:null,win:X,status:0,defMinDate:_.minDate,defMaxDate:_.maxDate,flatCfgs:[]};B();if($dp.status==0)Z(X,function(){U(null,true)});if(!X[O].docMD){E(X[O],"onmousedown",D);X[O].docMD=true}if(!V[O].docMD){E(V[O],"onmousedown",D);V[O].docMD=true}E(X,"onunload",function(){if($dp.dd)Q($dp.dd,"none")});function B(){V.$dp=V.$dp||{};obj={$:function($){return(typeof $=="string")?this.win[O].getElementById($):$},$D:function($,_){return this.$DV(this.$($).value,_)},$DV:function(_,$){if(_!=""){this.dt=$dp.cal.splitDate(_,$dp.cal.dateFmt);if($)for(var A in $){if(this.dt[A]===undefined)this.errMsg="invalid property:"+A;this.dt[A]+=$[A]}if(this.dt.refresh())return this.dt}return""},show:function(){Q(this.dd,"block")},hide:function(){Q(this.dd,"none")},attachEvent:E};for(var $ in obj)V.$dp[$]=obj[$];$dp=V.$dp}function E(A,$,_){if(T)A.attachEvent($,_);else{var B=$.replace(/on/,"");_._ieEmuEventHandler=function($){return _($)};A.addEventListener(B,_._ieEmuEventHandler,false)}}function L(){var _,A,$=X[O][C]("script");for(var B=0;B<$.length;B++){_=$[B].src.substring(0,$[B].src.toLowerCase().indexOf("wdatepicker.js"));A=_.lastIndexOf("/");if(A>0)_=_.substring(0,A+1);if(_)break}return _}function F(F){var E,C;if(F.substring(0,1)!="/"&&F.indexOf("://")==-1){E=V.location.href;C=location.href;if(E.indexOf("?")>-1)E=E.substring(0,E.indexOf("?"));if(C.indexOf("?")>-1)C=C.substring(0,C.indexOf("?"));var G,I,$="",D="",A="",J,H,B="";for(J=0;J_.scrollLeft||A.scrollLeft>_.scrollLeft))?A:_;return{"top":B.scrollTop,"left":B.scrollLeft}}function D($){src=$?($.srcElement||$.target):null;if($dp&&$dp.cal&&!$dp.eCont&&$dp.dd&&Q($dp.dd)=="block"&&src!=$dp.el)$dp.cal.close()}function Y(){$dp.status=2;H()}function H(){if($dp.flatCfgs.length>0){var $=$dp.flatCfgs.shift();$.el={innerHTML:""};$.autoPickDate=true;$.qsEnabled=false;K($)}}var R,$;function U(E,_){$dp.win=X;B();E=E||{};if(_){if(!D()){$=$||setInterval(function(){if(V[O].readyState=="complete")clearInterval($);U(null,true)},50);return}if($dp.status==0){$dp.status=1;K({el:{innerHTML:""}},true)}else return}else if(E.eCont){E.eCont=$dp.$(E.eCont);$dp.flatCfgs.push(E);if($dp.status==2)H()}else{if($dp.status==0){U(null,true);return}if($dp.status!=2)return;var C=A();if(C){$dp.srcEl=C.srcElement||C.target;C.cancelBubble=true}E.el=$dp.$(E.el||$dp.srcEl);if(!E.el||E.el.disabled||(E.el==$dp.el&&Q($dp.dd)!="none"&&$dp.dd.style.left!="-1970px"))return;K(E)}function D(){if(T&&V!=X&&V[O].readyState!="complete")return false;return true}function A(){if(I){func=A.caller;while(func!=null){var $=func.arguments[0];if($&&($+"").indexOf("Event")>=0)return $;func=func.caller}return null}return event}}function S(_,$){return _.currentStyle?_.currentStyle[$]:document.defaultView.getComputedStyle(_,false)[$]}function Q(_,$){if(_)if($!=null)_.style.display=$;else return S(_,"display")}function K(H,$){for(var D in _)if(D.substring(0,1)!="$")$dp[D]=_[D];for(D in H)if($dp[D]===undefined)$dp.errMsg="invalid property:"+D;else $dp[D]=H[D];var E=$dp.el?$dp.el.nodeName:"INPUT";if($||$dp.eCont||new RegExp(/input|textarea|div|span|p|a/ig).test(E))$dp.elProp=E=="INPUT"?"value":"innerHTML";else return;if($dp.lang=="auto")$dp.lang=T?navigator.browserLanguage.toLowerCase():navigator.language.toLowerCase();if(!$dp.dd||$dp.eCont||($dp.lang&&$dp.realLang&&$dp.realLang.name!=$dp.lang&&$dp.getLangIndex&&$dp.getLangIndex($dp.lang)>=0)){if($dp.dd&&!$dp.eCont)V[O].body.removeChild($dp.dd);if(_.$dpPath=="")F(A);var B="";if($dp.eCont){$dp.eCont.innerHTML=B;Z($dp.eCont.childNodes[0],Y)}else{$dp.dd=V[O].createElement("DIV");$dp.dd.style.cssText="position:absolute;z-index:19700";$dp.dd.innerHTML=B;V[O].body.insertBefore($dp.dd,V[O].body.firstChild);Z($dp.dd.childNodes[0],Y);if($)$dp.dd.style.left=$dp.dd.style.top="-1970px";else{$dp.show();C()}}}else if($dp.cal){$dp.show();$dp.cal.init();if(!$dp.eCont)C()}function C(){var F=$dp.position.left,B=$dp.position.top,C=$dp.el;if(C!=$dp.srcEl&&(Q(C)=="none"||C.type=="hidden"))C=$dp.srcEl;var H=W(C),$=G(X),D=N(V),A=a(V),E=$dp.dd.offsetHeight,_=$dp.dd.offsetWidth;if(isNaN(B)){if(B=="above"||(B!="under"&&(($.topM+H.bottom+E>D.height)&&($.topM+H.top-E>0))))B=A.top+$.topM+H.top-E-3;else B=A.top+$.topM+H.bottom;B+=T?-1:1}else B+=A.top+$.topM;if(isNaN(F))F=A.left+Math.min($.leftM+H.left,D.width-_-5)-(T?2:0);else F+=A.left+$.leftM;$dp.dd.style.top=B+"px";$dp.dd.style.left=F+"px"}}})() ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/js/My97DatePicker/calendar.js ================================================ /* * My97 DatePicker 4.6 Prerelease * SITE: http://dp.my97.net * BLOG: http://my97.cnblogs.com * MAIL: smallcarrot@163.com */ eval(function(B,D,A,G,E,F){function C(A){return A<62?String.fromCharCode(A+=A<26?65:A<52?71:-4):A<63?'_':A<64?'$':C(A>>6)+C(A&63)}while(A>0)E[C(G--)]=D[--A];return B.replace(/[\w\$]+/g,function(A){return E[A]==F[A]?A:E[A]})}('k g;d(FI){E8.Ca.__defineSetter__("C$",_(b){d(!b){q.Bm();}6 b;});E8.Ca.__defineGetter__("FE",_(){k b=q.Fz;CK(b.FO!=U){b=b.parentNode;}6 b;});HTMLElement.Ca.Cu=_(a,A){k b=a.8(/Es/,"");A.Ed=_(b){Fu.BI=b;6 A();};q.addEventListener(b,A.Ed,z);};}_ EN(){g=q;q.CW=[];c=CS.createElement("m");c.$="EB";c.BQ=\'<5 B4=T By=T Bw=T>&Dj;\';EJ(c,_(){Cs();});a();q.FX();b();D8("S,K,H,P,R");c.EM.9=_(){D7(U);};c.El.9=_(){D7(-U);};c.ED.9=_(){d(c.BV.3.De!="Fo"){g.D1();C6(c.BV);}r{t(c.BV);}};EJ(c.Cn,_(){d(j.Bj.3.De!="E7"){c.BO.EC();}BI.C$=z;});CS.body.EL(c);_ a(){k a=b("L");x=b("m"),BS=b("BH"),EA=b("BZ"),FJ=b("Dg");c.DN=a[T];c.Ck=a[U];c.DO=a[W];c.Cz=a[V];c.C3=x[Z];c.BO=BS[T];c.BG=BS[U];c.Do=x[T];c.Ct=x[BA];c.CN=x[BJ];c.BV=x[B3];c.CT=x[Dy];c.EK=x[CR];c.EX=x[13];c.FA=x[14];c.Fe=x[Dx];c.ED=x[16];c.Ef=x[17];c.C2=BS[V];c.Ds=BS[BA];c.D5=BS[BJ];c.Cv=BS[Y];c.Bx=BS[Ci];c.Cn=BS[Z];c.EM=EA[T];c.El=EA[U];c.Fj=FJ[T];_ b(b){6 c.DW(b);}}_ b(){c.DN.9=_(){BN=BN<=T?BN-U:-U;d(BN%X==T){c.BG.EC();6;}c.BG.2=l.S-U;c.BG.CC();};c.Ck.9=_(){l.v("K",-U);c.BO.CC();};c.DO.9=_(){l.v("K",U);c.BO.CC();};c.Cz.9=_(){BN=BN>=T?BN+U:U;d(BN%X==T){c.BG.EC();6;}c.BG.2=l.S+U;c.BG.CC();};}}EN.Ca={FX:_(){BN=T;j.DH=q;d(j.Cm&&j.f.Cm!=w){j.f.Cm=s;j.f.Dt();}b();q.Bi=j.Bi;q.E6();q.CD=j.CD==w?(j.n.Bb&&j.n.Bb?z:s):j.CD;l=q.Eu=o BP();BF=o BP();Bl=q.B2=o BP();q.FK=q.Cd("disabledDates");q.FD=q.Cd("disabledDays");q.E3=q.Cd("specialDates");q.FY=q.Cd("specialDays");q.BY=q.C0(j.BY,j.BY!=j.Ej?j.Bg:j.CL,j.Ej);q.Bc=q.C0(j.Bc,j.Bc!=j.Fv?j.Bg:j.CL,j.Fv);d(q.BY.Br(q.Bc)>T){j.D3=1.err_1;}d(q.BW()){q.Ei();q.B_=j.f[j.BE];}r{q.Bh(z,V);}i("S");i("K");i("M");i("H");i("P");i("R");c.Fj.BQ=1.timeStr;c.Cv.2=1.clearStr;c.Bx.2=1.todayStr;c.Cn.2=1.okStr;q.EW();q.Ex();d(j.D3){alert(j.D3);}q.D_();Cs();d(j.f.FO==U){j.Cu(j.f,"EF",_(b){d(j.f==(b.FE||b.Fz)){Ea=(b.Bu==CY)?b.D6:b.Bu;d(Ea==Z){d(!j.DH.Du()){b.Bm?b.Bm():b.C$=z;j.DH.Bh(z,V);j.Bq();}r{j.DH.Bh(s);j.t();}}}});}_ b(){k a,b;p(a=T;(b=CS.DW("link")[a]);a++){d(v(b,"rel").BL("3")!=-U&&v(b,"Fp")){b.Bv=s;d(v(b,"Fp")==j.skin){b.Bv=z;}}}}},Ei:_(){k A=q.Cg(),b=s;d(A!=T){b=z;k a;d(A>T){a=q.Bc;}r{a=q.BY;}d(j.n.DD){l.S=a.S;l.K=a.K;l.M=a.M;}d(j.n.Bb){l.H=a.H;l.P=a.P;l.R=a.R;}}6 b;},Cp:_(K,F,EV,a,D,B,A,EU,G){k E;d(K&&K.BW){E=K;}r{E=o BP();d(K!=""){F=F||j.Bi;k J,DX=T,I,C=/Cw|Cf|DR|S|B7|CQ|Dl|K|Bj|M|E4|H|E1|P|FU|R|B9|D|Dz|B$|Cl/BX,CA=F.EI(C);C.C_=T;d(G){I=K.Dv(/\\B$+/);}r{k b=T,H="^";CK((I=C.DF(F))!==w){d(b>T){H+=F.CM(b,I.DB);}b=I.DB-b;b=C.C_;Cb(I[T]){u"Cw":H+="(\\\\M{BA})";0;u"Cf":H+="(\\\\M{W})";0;Ft:d(o Ch("B7|CQ|B9|D|Dz|B$|Cl").D9(I[T])){H+="(\\\\D+)";}r{H+="(\\\\M\\\\M?)";}0;}}H+=".*b";I=o Ch(H).DF(K);DX=U;}d(I){p(J=T;J=T){b=b.8(/%E$/BX,"T");a.M=T;a.K=DE(a.K)+U;}a.CI();}6 a;},BW:_(){k A,a;d(j.alwaysUseStartDate||(j.ES!=""&&j.f[j.BE]=="")){A=q.C5(j.ES);a=j.Bg;}r{A=j.f[j.BE];a=q.Bi;}l.CZ(q.Cp(A,a));d(A!=""){k b=U;d(j.n.DD&&!q.DP(l)){l.S=BF.S;l.K=BF.K;l.M=BF.M;b=T;}d(j.n.Bb&&!q.Db(l)){l.H=BF.H;l.P=BF.P;l.R=BF.R;b=T;}6 b&&q.BR(l);}6 U;},DP:_(b){d(b.S!=w){b=CH(b.S,BA)+"-"+b.K+"-"+b.M;}6 b.EI(/^((\\M{V}(([Em][048])|([Ey][26]))[\\-\\/\\R]?((((T?[E0])|(U[FQ]))[\\-\\/\\R]?((T?[U-Z])|([U-V][T-Z])|(W[FP])))|(((T?[Eo])|(Dy))[\\-\\/\\R]?((T?[U-Z])|([U-V][T-Z])|(CP)))|(T?V[\\-\\/\\R]?((T?[U-Z])|([U-V][T-Z])))))|(\\M{V}(([Em][1235679])|([Ey][01345789]))[\\-\\/\\R]?((((T?[E0])|(U[FQ]))[\\-\\/\\R]?((T?[U-Z])|([U-V][T-Z])|(W[FP])))|(((T?[Eo])|(Dy))[\\-\\/\\R]?((T?[U-Z])|([U-V][T-Z])|(CP)))|(T?V[\\-\\/\\R]?((T?[U-Z])|(U[T-Z])|(V[T-Ci]))))))(\\R(((T?[T-Z])|([U-V][T-W]))\\:([T-X]?[T-Z])((\\R)|(\\:([T-X]?[T-Z])))))?b/);},Db:_(b){d(b.H!=w){b=b.H+":"+b.P+":"+b.R;}6 b.EI(/^([T-Z]|([T-U][T-Z])|([V][T-W])):([T-Z]|([T-X][T-Z])):([T-Z]|([T-X][T-Z]))b/);},Cg:_(b,a){a=a||l;k A=a.Br(q.BY,b);d(A>T){A=a.Br(q.Bc,b);d(AU){C-=Y;}G.L("<5 y=Fn DC=EE% Bw=T B4=T By=T>");G.L("");d(j.FV){G.L(""+A[T]+"");}p(a=T;a"+A[(B+a)%Y+U]+"");}G.L("");p(a=U,F=C;a");p(b=T;b"+Dk(J,U)+"");}G.L(""+J.M+"");}r{G.L(">");}}G.L("");}G.L("");6 G.O();},FT:_(b){6 q.Dr(b,q.FK);},Ev:_(b){6 q.Dq(b,q.FD);},Fk:_(b){6 q.Dr(b,q.E3,U);},FM:_(b){6 q.Dq(b,q.FY,U);},Dr:_(A,b){k a=b&&b.D9(q.C7(j.Bg,A));6 a;},Dq:_(b,A){k a=A&&A.D9(b);6 a;},Cc:_(Q,BC,Da,EY,Bp){k R=o B5(),DU=Bp?"Da"+Q:Q;Et=l[Q];R.L("<5 B4=T By=W Bw=T");p(k N=T;N\');p(k O=T;O"+(Q=="K"?1.Bt[l[Q]-U]:l[Q])+"");}R.L("");}R.L("");l[Q]=Et;6 R.O();},DT:_(a,A){d(a){k b=a.offsetLeft;d(EZ){b=a.getBoundingClientRect().CB;}A.3.CB=b;}},_fM:_(b){q.DT(b,c.Ct);c.Ct.BQ=q.Cc("K",V,BJ,"N+O*BJ+U",b==c.Bn);},Dc:_(A,b){k a=o B5();b=CX(b,l.S-X);a.L(q.Cc("S",V,X,b+"+N+O*X",A==c.B0));a.L("<5 B4=T By=W Bw=T Dd=D$>\\u2190\\E9b+B3?"y=\'BD\' B6=\\"q.$=\'CV\'\\" Bs=\\"q.$=\'BD\'\\" Cx=\'d(BI.Bm)BI.Bm();BI.EP=s;g.Dc(T,"+(b+B3)+")\'":"y=\'Dn\'");a.L(">\\u2192");q.DT(A,c.CN);c.CN.BQ=a.O();},DM:_(b,A,a){c[b+"D"].BQ=q.Cc(b,BJ,A,a);},_fH:_(){q.DM("H",BA,"N * BJ + O");},_fm:_(){q.DM("P",V,"N * CP + O * X");},_fs:_(){q.DM("R",U,"O * B3");},D1:_(b){q.Fi();k C=q.CW,B=C.3,A=o B5();A.L(\'<5 y=Fn DC="\'+c.CT.FF+\'DJ" Eh="\'+c.CT.Eb+\'DJ" Bw=T B4=T By=T>\');A.L(\'\'+1.quickStr+"");d(!b){A.L(\'\\E9\');}A.L("");p(k a=T;a\');A.L("&Dj;"+q.C7(w,C[a]));A.L("");}r{A.L("&Dj;");}}A.L("");c.BV.BQ=A.O();},E6:_(){b(/Cl/);b(/Dz|B$/);b(/B9|D/);b(/Cw|Cf|DR|S/);b(/B7|CQ|Dl|K/);b(/Bj|M/);b(/E4|H/);b(/E1|P/);b(/FU|R/);j.n.DD=(j.n.S||j.n.K||j.n.M)?s:z;j.n.Bb=(j.n.H||j.n.P||j.n.R)?s:z;j.CL=j.CL.8(/%BU/,j.Fw).8(/%Time/,j.Fc);d(j.n.DD){d(j.n.Bb){j.Bg=j.CL;}r{j.Bg=j.Fw;}}r{j.Bg=j.Fc;}_ b(a){k b=(a+"").D0(U,V);j.n[b]=a.DF(j.Bi)?(j.n.DV=b,s):z;}},EW:_(){k b=T;j.n.S?(b=U,Bq(c.BG,c.DN,c.Cz)):t(c.BG,c.DN,c.Cz);j.n.K?(b=U,Bq(c.BO,c.Ck,c.DO)):t(c.BO,c.Ck,c.DO);b?Bq(c.Do):t(c.Do);d(j.n.Bb){Bq(c.EK);DI(c.C2,j.n.H);DI(c.Ds,j.n.P);DI(c.D5,j.n.R);}r{t(c.EK);}C1(c.Cv,j.isShowClear);C1(c.Bx,j.isShowToday);C1(c.ED,(j.n.M&&j.qsEnabled));d(j.Fb){t(c.Ef);}},Bh:_(B,b){k a=j.f,D=FI?"y":"$";d(B){C(a);}r{d(b==w){b=j.errDealMode;}Cb(b){u T:d(confirm(1.errAlertMsg)){a[j.BE]=q.B_;C(a);}r{A(a);}0;u U:a[j.BE]=q.B_;C(a);0;u V:A(a);0;}}_ C(b){k A=b.$;d(A){k a=A.8(/Fl/BX,"");d(A!=a){v(b,D,a);}}}_ A(b){v(b,D,b.$+" Fl");}},Ba:_(b,G,E){E=E||Bl;k H,F=[b+b,b],a,C=E[b],A=_(b){6 CH(C,b.7);};Cb(b.Bz(T)){u"Cl":C=Be(E);0;u"D":k B=Be(E)+U;A=_(b){6 b.7==V?1.aLongWeekStr[B]:1.Fr[B];};0;u"B$":C=Dk(E);0;u"S":F=["Cw","Cf","DR","S"];G=G||F[T];A=_(b){6 CH((b.7=T){D[H]=A(a);G=G.8(a,"{"+H+"}");}}p(H=T;H");b.L(q.Cr());b.L("");l.v("K",U);b.L(q.Cr());c.Bn=c.BO.FC(s);c.B0=c.BG.FC(s);c.C3.EL(c.Bn);c.C3.EL(c.B0);c.Bn.2=1.Bt[l.K-U];v(c.Bn,"DL",l.K);c.B0.2=l.S;D8("Fh,FZ");c.Bn.$=c.B0.$="Ce";l.v("K",-U);b.L("");c.CT.BQ=b.O();}r{c.$="EB";c.CT.BQ=q.Cr();}d(!j.n.M){q.D1(s);C6(c.BV);}r{t(c.BV);}q.E5();},E5:_(){k b=parent.CS.DW("iframe");p(k a=T;aT){l.M--;}q.Dh();d(!j.Fb){d(q.BR(l)){g.Bh(s);t(j.Bj);}r{g.Bh(z);}}d(j.ET){Bk("ET");}r{d(q.B_!=j.f[j.BE]&&j.f.Fx){C9(j.f,"Eg");}}},Ex:_(){c.Cv.9=_(){d(!Bk("onclearing")){j.f[j.BE]="";g.Cy("");t(j.Bj);d(j.Fm){Bk("Fm");}r{d(g.B_!=j.f[j.BE]&&j.f.Fx){C9(j.f,"Eg");}}}};c.Cn.9=_(){CG();};d(q.BR(BF)){c.Bx.Bv=z;c.Bx.9=_(){l.CZ(BF);CG();};}r{c.Bx.Bv=s;}},Fi:_(){k H,B,C,A,F=[],E=X,a=j.E_.7,G=j.n.DV;d(a>E){a=E;}r{d(G=="P"||G=="R"){F=[T,Dx,CP,Fg,Fa,-60,-Fg,-CP,-Dx,-U];}r{p(H=T;H=T){BT=Co(BT,T,Fa);}}}d(Bl[Q]!=BT&&!Bk(Q+"changing")){k Fs=\'i("\'+Q+\'",\'+BT+")",DG=g.Cg();d(DG==T){CO(Fs);}r{d(DGT){Dm(g.Bc);}}}d(!FR&&"yMd".BL(Q)>=T){g.D_();}Bk(Q+"changed");}_ Dm(b){i("S",b.S);i("K",b.K);i("M",b.M);d(j.n.Bb){i("H",b.H);i("P",b.P);i("R",b.R);}}}_ CG(A,D,F,b,E,B){k C=o BP(l.S,l.K,l.M,l.H,l.P,l.R);l.BW(A,D,F,b,E,B);d(!Bk("onpicking")){k a=C.S==A&&C.K==D&&C.M==F;d(!a&&CU.7!=T){BC("S",A,s);BC("K",D,s);BC("M",F);}d(g.CD||a||CU.7==T){g.ER();}}r{l=C;}}_ Bk(b){k a;d(j[b]){a=j[b].call(j.f,j);}6 a;}_ i(a,b){b=b||l[a];Bl[a]=l[a]=b;d("yHms".BL(a)>=T){c[a+"BK"].2=b;}d(a=="K"){v(c.BO,"DL",b);c.BO.2=1.Bt[b-U];}}_ v(b,A,a){d(a===CY){6 b.getAttribute(A);}r{d(b.FL){b.FL(A,a);}}}_ Co(A,a,b){d(Ab){A=b;}}6 A;}_ EJ(b,a){b.Cu("EF",_(){k A=BI,b=(A.Bu==CY)?A.D6:A.Bu;d(b==Z){a();}});}_ CH(b,a){b=b+"";CK(b.7=T?C:X;p(k b=T;b<=C;b++){A=a.Bz(b);D=q[A]-B[A];d(D>T){6 U;}r{d(D=T){k b=q.M;q.M=U;q[A]+=a;q.CI();q.M=b;}}};_ DE(b){6 parseInt(b,B3);}_ CF(b,a){6 CX(DE(b),a);}_ 4(a,b,A){6 CF(a,CX(b,A));}_ CX(b,a){6 b==w||FN(b)?a:b;}_ C9(b,a){d(EZ){b.C9("Es"+a);}r{k A=CS.createEvent("HTMLEvents");A.initEvent(a,s,s);b.dispatchEvent(A);}}_ EG(A){k b,a,B="S,K,H,P,R,FZ,Fh".Dv(",");p(a=T;a=48&&a<=57)||(a>=96&&a<=105)||a==Ci||a==46||a==37||a==39||a==Z)){b.C$=z;}}_ D8(A){k b=A.Dv(",");p(k a=T;a li > a:hover, .dropdown-menu > li > a:focus { background-color: #e8e8e8; background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); background-repeat: repeat-x; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { background-color: #2e6da4; background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); background-repeat: repeat-x; } .navbar-default { background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; border-radius: 4px; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .active > a { background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); background-repeat: repeat-x; -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); } .navbar-brand, .navbar-nav > li > a { text-shadow: 0 1px 0 rgba(255, 255, 255, .25); } .navbar-inverse { background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); background-repeat: repeat-x; } .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .active > a { background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); background-repeat: repeat-x; -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); } .navbar-inverse .navbar-brand, .navbar-inverse .navbar-nav > li > a { text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); } .navbar-static-top, .navbar-fixed-top, .navbar-fixed-bottom { border-radius: 0; } @media (max-width: 767px) { .navbar .navbar-nav .open .dropdown-menu > .active > a, .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { color: #fff; background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); background-repeat: repeat-x; } } .alert { text-shadow: 0 1px 0 rgba(255, 255, 255, .2); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); } .alert-success { background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); background-repeat: repeat-x; border-color: #b2dba1; } .alert-info { background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); background-repeat: repeat-x; border-color: #9acfea; } .alert-warning { background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); background-repeat: repeat-x; border-color: #f5e79e; } .alert-danger { background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); background-repeat: repeat-x; border-color: #dca7a7; } .progress { background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); background-repeat: repeat-x; } .progress-bar { background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); background-repeat: repeat-x; } .progress-bar-success { background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); background-repeat: repeat-x; } .progress-bar-info { background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); background-repeat: repeat-x; } .progress-bar-warning { background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); background-repeat: repeat-x; } .progress-bar-danger { background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); background-repeat: repeat-x; } .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .list-group { border-radius: 4px; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); box-shadow: 0 1px 2px rgba(0, 0, 0, .075); } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { text-shadow: 0 -1px 0 #286090; background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); background-repeat: repeat-x; border-color: #2b669a; } .list-group-item.active .badge, .list-group-item.active:hover .badge, .list-group-item.active:focus .badge { text-shadow: none; } .panel { -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); box-shadow: 0 1px 2px rgba(0, 0, 0, .05); } .panel-default > .panel-heading { background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); background-repeat: repeat-x; } .panel-primary > .panel-heading { background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); background-repeat: repeat-x; } .panel-success > .panel-heading { background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); background-repeat: repeat-x; } .panel-info > .panel-heading { background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); background-repeat: repeat-x; } .panel-warning > .panel-heading { background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); background-repeat: repeat-x; } .panel-danger > .panel-heading { background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); background-repeat: repeat-x; } .well { background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); background-repeat: repeat-x; border-color: #dcdcdc; -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); } /*# sourceMappingURL=bootstrap-theme.css.map */ ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/js/bootstrap-3.3.2-dist/css/bootstrap.css ================================================ /*! * Bootstrap v3.3.2 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ html { font-family: sans-serif; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } body { margin: 0; } article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary { display: block; } audio, canvas, progress, video { display: inline-block; vertical-align: baseline; } audio:not([controls]) { display: none; height: 0; } [hidden], template { display: none; } a { background-color: transparent; } a:active, a:hover { outline: 0; } abbr[title] { border-bottom: 1px dotted; } b, strong { font-weight: bold; } dfn { font-style: italic; } h1 { margin: .67em 0; font-size: 2em; } mark { color: #000; background: #ff0; } small { font-size: 80%; } sub, sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline; } sup { top: -.5em; } sub { bottom: -.25em; } img { border: 0; } svg:not(:root) { overflow: hidden; } figure { margin: 1em 40px; } hr { height: 0; -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } pre { overflow: auto; } code, kbd, pre, samp { font-family: monospace, monospace; font-size: 1em; } button, input, optgroup, select, textarea { margin: 0; font: inherit; color: inherit; } button { overflow: visible; } button, select { text-transform: none; } button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; cursor: pointer; } button[disabled], html input[disabled] { cursor: default; } button::-moz-focus-inner, input::-moz-focus-inner { padding: 0; border: 0; } input { line-height: normal; } input[type="checkbox"], input[type="radio"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 0; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { height: auto; } input[type="search"] { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; -webkit-appearance: textfield; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } fieldset { padding: .35em .625em .75em; margin: 0 2px; border: 1px solid #c0c0c0; } legend { padding: 0; border: 0; } textarea { overflow: auto; } optgroup { font-weight: bold; } table { border-spacing: 0; border-collapse: collapse; } td, th { padding: 0; } /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ @media print { *, *:before, *:after { color: #000 !important; text-shadow: none !important; background: transparent !important; -webkit-box-shadow: none !important; box-shadow: none !important; } a, a:visited { text-decoration: underline; } a[href]:after { content: " (" attr(href) ")"; } abbr[title]:after { content: " (" attr(title) ")"; } a[href^="#"]:after, a[href^="javascript:"]:after { content: ""; } pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } select { background: #fff !important; } .navbar { display: none; } .btn > .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px solid #000; } .table { border-collapse: collapse !important; } .table td, .table th { background-color: #fff !important; } .table-bordered th, .table-bordered td { border: 1px solid #ddd !important; } } @font-face { font-family: 'Glyphicons Halflings'; src: url('../fonts/glyphicons-halflings-regular.eot'); src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); } .glyphicon { position: relative; top: 1px; display: inline-block; font-family: 'Glyphicons Halflings'; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .glyphicon-asterisk:before { content: "\2a"; } .glyphicon-plus:before { content: "\2b"; } .glyphicon-euro:before, .glyphicon-eur:before { content: "\20ac"; } .glyphicon-minus:before { content: "\2212"; } .glyphicon-cloud:before { content: "\2601"; } .glyphicon-envelope:before { content: "\2709"; } .glyphicon-pencil:before { content: "\270f"; } .glyphicon-glass:before { content: "\e001"; } .glyphicon-music:before { content: "\e002"; } .glyphicon-search:before { content: "\e003"; } .glyphicon-heart:before { content: "\e005"; } .glyphicon-star:before { content: "\e006"; } .glyphicon-star-empty:before { content: "\e007"; } .glyphicon-user:before { content: "\e008"; } .glyphicon-film:before { content: "\e009"; } .glyphicon-th-large:before { content: "\e010"; } .glyphicon-th:before { content: "\e011"; } .glyphicon-th-list:before { content: "\e012"; } .glyphicon-ok:before { content: "\e013"; } .glyphicon-remove:before { content: "\e014"; } .glyphicon-zoom-in:before { content: "\e015"; } .glyphicon-zoom-out:before { content: "\e016"; } .glyphicon-off:before { content: "\e017"; } .glyphicon-signal:before { content: "\e018"; } .glyphicon-cog:before { content: "\e019"; } .glyphicon-trash:before { content: "\e020"; } .glyphicon-home:before { content: "\e021"; } .glyphicon-file:before { content: "\e022"; } .glyphicon-time:before { content: "\e023"; } .glyphicon-road:before { content: "\e024"; } .glyphicon-download-alt:before { content: "\e025"; } .glyphicon-download:before { content: "\e026"; } .glyphicon-upload:before { content: "\e027"; } .glyphicon-inbox:before { content: "\e028"; } .glyphicon-play-circle:before { content: "\e029"; } .glyphicon-repeat:before { content: "\e030"; } .glyphicon-refresh:before { content: "\e031"; } .glyphicon-list-alt:before { content: "\e032"; } .glyphicon-lock:before { content: "\e033"; } .glyphicon-flag:before { content: "\e034"; } .glyphicon-headphones:before { content: "\e035"; } .glyphicon-volume-off:before { content: "\e036"; } .glyphicon-volume-down:before { content: "\e037"; } .glyphicon-volume-up:before { content: "\e038"; } .glyphicon-qrcode:before { content: "\e039"; } .glyphicon-barcode:before { content: "\e040"; } .glyphicon-tag:before { content: "\e041"; } .glyphicon-tags:before { content: "\e042"; } .glyphicon-book:before { content: "\e043"; } .glyphicon-bookmark:before { content: "\e044"; } .glyphicon-print:before { content: "\e045"; } .glyphicon-camera:before { content: "\e046"; } .glyphicon-font:before { content: "\e047"; } .glyphicon-bold:before { content: "\e048"; } .glyphicon-italic:before { content: "\e049"; } .glyphicon-text-height:before { content: "\e050"; } .glyphicon-text-width:before { content: "\e051"; } .glyphicon-align-left:before { content: "\e052"; } .glyphicon-align-center:before { content: "\e053"; } .glyphicon-align-right:before { content: "\e054"; } .glyphicon-align-justify:before { content: "\e055"; } .glyphicon-list:before { content: "\e056"; } .glyphicon-indent-left:before { content: "\e057"; } .glyphicon-indent-right:before { content: "\e058"; } .glyphicon-facetime-video:before { content: "\e059"; } .glyphicon-picture:before { content: "\e060"; } .glyphicon-map-marker:before { content: "\e062"; } .glyphicon-adjust:before { content: "\e063"; } .glyphicon-tint:before { content: "\e064"; } .glyphicon-edit:before { content: "\e065"; } .glyphicon-share:before { content: "\e066"; } .glyphicon-check:before { content: "\e067"; } .glyphicon-move:before { content: "\e068"; } .glyphicon-step-backward:before { content: "\e069"; } .glyphicon-fast-backward:before { content: "\e070"; } .glyphicon-backward:before { content: "\e071"; } .glyphicon-play:before { content: "\e072"; } .glyphicon-pause:before { content: "\e073"; } .glyphicon-stop:before { content: "\e074"; } .glyphicon-forward:before { content: "\e075"; } .glyphicon-fast-forward:before { content: "\e076"; } .glyphicon-step-forward:before { content: "\e077"; } .glyphicon-eject:before { content: "\e078"; } .glyphicon-chevron-left:before { content: "\e079"; } .glyphicon-chevron-right:before { content: "\e080"; } .glyphicon-plus-sign:before { content: "\e081"; } .glyphicon-minus-sign:before { content: "\e082"; } .glyphicon-remove-sign:before { content: "\e083"; } .glyphicon-ok-sign:before { content: "\e084"; } .glyphicon-question-sign:before { content: "\e085"; } .glyphicon-info-sign:before { content: "\e086"; } .glyphicon-screenshot:before { content: "\e087"; } .glyphicon-remove-circle:before { content: "\e088"; } .glyphicon-ok-circle:before { content: "\e089"; } .glyphicon-ban-circle:before { content: "\e090"; } .glyphicon-arrow-left:before { content: "\e091"; } .glyphicon-arrow-right:before { content: "\e092"; } .glyphicon-arrow-up:before { content: "\e093"; } .glyphicon-arrow-down:before { content: "\e094"; } .glyphicon-share-alt:before { content: "\e095"; } .glyphicon-resize-full:before { content: "\e096"; } .glyphicon-resize-small:before { content: "\e097"; } .glyphicon-exclamation-sign:before { content: "\e101"; } .glyphicon-gift:before { content: "\e102"; } .glyphicon-leaf:before { content: "\e103"; } .glyphicon-fire:before { content: "\e104"; } .glyphicon-eye-open:before { content: "\e105"; } .glyphicon-eye-close:before { content: "\e106"; } .glyphicon-warning-sign:before { content: "\e107"; } .glyphicon-plane:before { content: "\e108"; } .glyphicon-calendar:before { content: "\e109"; } .glyphicon-random:before { content: "\e110"; } .glyphicon-comment:before { content: "\e111"; } .glyphicon-magnet:before { content: "\e112"; } .glyphicon-chevron-up:before { content: "\e113"; } .glyphicon-chevron-down:before { content: "\e114"; } .glyphicon-retweet:before { content: "\e115"; } .glyphicon-shopping-cart:before { content: "\e116"; } .glyphicon-folder-close:before { content: "\e117"; } .glyphicon-folder-open:before { content: "\e118"; } .glyphicon-resize-vertical:before { content: "\e119"; } .glyphicon-resize-horizontal:before { content: "\e120"; } .glyphicon-hdd:before { content: "\e121"; } .glyphicon-bullhorn:before { content: "\e122"; } .glyphicon-bell:before { content: "\e123"; } .glyphicon-certificate:before { content: "\e124"; } .glyphicon-thumbs-up:before { content: "\e125"; } .glyphicon-thumbs-down:before { content: "\e126"; } .glyphicon-hand-right:before { content: "\e127"; } .glyphicon-hand-left:before { content: "\e128"; } .glyphicon-hand-up:before { content: "\e129"; } .glyphicon-hand-down:before { content: "\e130"; } .glyphicon-circle-arrow-right:before { content: "\e131"; } .glyphicon-circle-arrow-left:before { content: "\e132"; } .glyphicon-circle-arrow-up:before { content: "\e133"; } .glyphicon-circle-arrow-down:before { content: "\e134"; } .glyphicon-globe:before { content: "\e135"; } .glyphicon-wrench:before { content: "\e136"; } .glyphicon-tasks:before { content: "\e137"; } .glyphicon-filter:before { content: "\e138"; } .glyphicon-briefcase:before { content: "\e139"; } .glyphicon-fullscreen:before { content: "\e140"; } .glyphicon-dashboard:before { content: "\e141"; } .glyphicon-paperclip:before { content: "\e142"; } .glyphicon-heart-empty:before { content: "\e143"; } .glyphicon-link:before { content: "\e144"; } .glyphicon-phone:before { content: "\e145"; } .glyphicon-pushpin:before { content: "\e146"; } .glyphicon-usd:before { content: "\e148"; } .glyphicon-gbp:before { content: "\e149"; } .glyphicon-sort:before { content: "\e150"; } .glyphicon-sort-by-alphabet:before { content: "\e151"; } .glyphicon-sort-by-alphabet-alt:before { content: "\e152"; } .glyphicon-sort-by-order:before { content: "\e153"; } .glyphicon-sort-by-order-alt:before { content: "\e154"; } .glyphicon-sort-by-attributes:before { content: "\e155"; } .glyphicon-sort-by-attributes-alt:before { content: "\e156"; } .glyphicon-unchecked:before { content: "\e157"; } .glyphicon-expand:before { content: "\e158"; } .glyphicon-collapse-down:before { content: "\e159"; } .glyphicon-collapse-up:before { content: "\e160"; } .glyphicon-log-in:before { content: "\e161"; } .glyphicon-flash:before { content: "\e162"; } .glyphicon-log-out:before { content: "\e163"; } .glyphicon-new-window:before { content: "\e164"; } .glyphicon-record:before { content: "\e165"; } .glyphicon-save:before { content: "\e166"; } .glyphicon-open:before { content: "\e167"; } .glyphicon-saved:before { content: "\e168"; } .glyphicon-import:before { content: "\e169"; } .glyphicon-export:before { content: "\e170"; } .glyphicon-send:before { content: "\e171"; } .glyphicon-floppy-disk:before { content: "\e172"; } .glyphicon-floppy-saved:before { content: "\e173"; } .glyphicon-floppy-remove:before { content: "\e174"; } .glyphicon-floppy-save:before { content: "\e175"; } .glyphicon-floppy-open:before { content: "\e176"; } .glyphicon-credit-card:before { content: "\e177"; } .glyphicon-transfer:before { content: "\e178"; } .glyphicon-cutlery:before { content: "\e179"; } .glyphicon-header:before { content: "\e180"; } .glyphicon-compressed:before { content: "\e181"; } .glyphicon-earphone:before { content: "\e182"; } .glyphicon-phone-alt:before { content: "\e183"; } .glyphicon-tower:before { content: "\e184"; } .glyphicon-stats:before { content: "\e185"; } .glyphicon-sd-video:before { content: "\e186"; } .glyphicon-hd-video:before { content: "\e187"; } .glyphicon-subtitles:before { content: "\e188"; } .glyphicon-sound-stereo:before { content: "\e189"; } .glyphicon-sound-dolby:before { content: "\e190"; } .glyphicon-sound-5-1:before { content: "\e191"; } .glyphicon-sound-6-1:before { content: "\e192"; } .glyphicon-sound-7-1:before { content: "\e193"; } .glyphicon-copyright-mark:before { content: "\e194"; } .glyphicon-registration-mark:before { content: "\e195"; } .glyphicon-cloud-download:before { content: "\e197"; } .glyphicon-cloud-upload:before { content: "\e198"; } .glyphicon-tree-conifer:before { content: "\e199"; } .glyphicon-tree-deciduous:before { content: "\e200"; } .glyphicon-cd:before { content: "\e201"; } .glyphicon-save-file:before { content: "\e202"; } .glyphicon-open-file:before { content: "\e203"; } .glyphicon-level-up:before { content: "\e204"; } .glyphicon-copy:before { content: "\e205"; } .glyphicon-paste:before { content: "\e206"; } .glyphicon-alert:before { content: "\e209"; } .glyphicon-equalizer:before { content: "\e210"; } .glyphicon-king:before { content: "\e211"; } .glyphicon-queen:before { content: "\e212"; } .glyphicon-pawn:before { content: "\e213"; } .glyphicon-bishop:before { content: "\e214"; } .glyphicon-knight:before { content: "\e215"; } .glyphicon-baby-formula:before { content: "\e216"; } .glyphicon-tent:before { content: "\26fa"; } .glyphicon-blackboard:before { content: "\e218"; } .glyphicon-bed:before { content: "\e219"; } .glyphicon-apple:before { content: "\f8ff"; } .glyphicon-erase:before { content: "\e221"; } .glyphicon-hourglass:before { content: "\231b"; } .glyphicon-lamp:before { content: "\e223"; } .glyphicon-duplicate:before { content: "\e224"; } .glyphicon-piggy-bank:before { content: "\e225"; } .glyphicon-scissors:before { content: "\e226"; } .glyphicon-bitcoin:before { content: "\e227"; } .glyphicon-yen:before { content: "\00a5"; } .glyphicon-ruble:before { content: "\20bd"; } .glyphicon-scale:before { content: "\e230"; } .glyphicon-ice-lolly:before { content: "\e231"; } .glyphicon-ice-lolly-tasted:before { content: "\e232"; } .glyphicon-education:before { content: "\e233"; } .glyphicon-option-horizontal:before { content: "\e234"; } .glyphicon-option-vertical:before { content: "\e235"; } .glyphicon-menu-hamburger:before { content: "\e236"; } .glyphicon-modal-window:before { content: "\e237"; } .glyphicon-oil:before { content: "\e238"; } .glyphicon-grain:before { content: "\e239"; } .glyphicon-sunglasses:before { content: "\e240"; } .glyphicon-text-size:before { content: "\e241"; } .glyphicon-text-color:before { content: "\e242"; } .glyphicon-text-background:before { content: "\e243"; } .glyphicon-object-align-top:before { content: "\e244"; } .glyphicon-object-align-bottom:before { content: "\e245"; } .glyphicon-object-align-horizontal:before { content: "\e246"; } .glyphicon-object-align-left:before { content: "\e247"; } .glyphicon-object-align-vertical:before { content: "\e248"; } .glyphicon-object-align-right:before { content: "\e249"; } .glyphicon-triangle-right:before { content: "\e250"; } .glyphicon-triangle-left:before { content: "\e251"; } .glyphicon-triangle-bottom:before { content: "\e252"; } .glyphicon-triangle-top:before { content: "\e253"; } .glyphicon-console:before { content: "\e254"; } .glyphicon-superscript:before { content: "\e255"; } .glyphicon-subscript:before { content: "\e256"; } .glyphicon-menu-left:before { content: "\e257"; } .glyphicon-menu-right:before { content: "\e258"; } .glyphicon-menu-down:before { content: "\e259"; } .glyphicon-menu-up:before { content: "\e260"; } * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } html { font-size: 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; line-height: 1.42857143; color: #333; background-color: #fff; } input, button, select, textarea { font-family: inherit; font-size: inherit; line-height: inherit; } a { color: #337ab7; text-decoration: none; } a:hover, a:focus { color: #23527c; text-decoration: underline; } a:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } figure { margin: 0; } img { vertical-align: middle; } .img-responsive, .thumbnail > img, .thumbnail a > img, .carousel-inner > .item > img, .carousel-inner > .item > a > img { display: block; max-width: 100%; height: auto; } .img-rounded { border-radius: 6px; } .img-thumbnail { display: inline-block; max-width: 100%; height: auto; padding: 4px; line-height: 1.42857143; background-color: #fff; border: 1px solid #ddd; border-radius: 4px; -webkit-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out; } .img-circle { border-radius: 50%; } hr { margin-top: 20px; margin-bottom: 20px; border: 0; border-top: 1px solid #eee; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } .sr-only-focusable:active, .sr-only-focusable:focus { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; } h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-family: inherit; font-weight: 500; line-height: 1.1; color: inherit; } h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { font-weight: normal; line-height: 1; color: #777; } h1, .h1, h2, .h2, h3, .h3 { margin-top: 20px; margin-bottom: 10px; } h1 small, .h1 small, h2 small, .h2 small, h3 small, .h3 small, h1 .small, .h1 .small, h2 .small, .h2 .small, h3 .small, .h3 .small { font-size: 65%; } h4, .h4, h5, .h5, h6, .h6 { margin-top: 10px; margin-bottom: 10px; } h4 small, .h4 small, h5 small, .h5 small, h6 small, .h6 small, h4 .small, .h4 .small, h5 .small, .h5 .small, h6 .small, .h6 .small { font-size: 75%; } h1, .h1 { font-size: 36px; } h2, .h2 { font-size: 30px; } h3, .h3 { font-size: 24px; } h4, .h4 { font-size: 18px; } h5, .h5 { font-size: 14px; } h6, .h6 { font-size: 12px; } p { margin: 0 0 10px; } .lead { margin-bottom: 20px; font-size: 16px; font-weight: 300; line-height: 1.4; } @media (min-width: 768px) { .lead { font-size: 21px; } } small, .small { font-size: 85%; } mark, .mark { padding: .2em; background-color: #fcf8e3; } .text-left { text-align: left; } .text-right { text-align: right; } .text-center { text-align: center; } .text-justify { text-align: justify; } .text-nowrap { white-space: nowrap; } .text-lowercase { text-transform: lowercase; } .text-uppercase { text-transform: uppercase; } .text-capitalize { text-transform: capitalize; } .text-muted { color: #777; } .text-primary { color: #337ab7; } a.text-primary:hover { color: #286090; } .text-success { color: #3c763d; } a.text-success:hover { color: #2b542c; } .text-info { color: #31708f; } a.text-info:hover { color: #245269; } .text-warning { color: #8a6d3b; } a.text-warning:hover { color: #66512c; } .text-danger { color: #a94442; } a.text-danger:hover { color: #843534; } .bg-primary { color: #fff; background-color: #337ab7; } a.bg-primary:hover { background-color: #286090; } .bg-success { background-color: #dff0d8; } a.bg-success:hover { background-color: #c1e2b3; } .bg-info { background-color: #d9edf7; } a.bg-info:hover { background-color: #afd9ee; } .bg-warning { background-color: #fcf8e3; } a.bg-warning:hover { background-color: #f7ecb5; } .bg-danger { background-color: #f2dede; } a.bg-danger:hover { background-color: #e4b9b9; } .page-header { padding-bottom: 9px; margin: 40px 0 20px; border-bottom: 1px solid #eee; } ul, ol { margin-top: 0; margin-bottom: 10px; } ul ul, ol ul, ul ol, ol ol { margin-bottom: 0; } .list-unstyled { padding-left: 0; list-style: none; } .list-inline { padding-left: 0; margin-left: -5px; list-style: none; } .list-inline > li { display: inline-block; padding-right: 5px; padding-left: 5px; } dl { margin-top: 0; margin-bottom: 20px; } dt, dd { line-height: 1.42857143; } dt { font-weight: bold; } dd { margin-left: 0; } @media (min-width: 768px) { .dl-horizontal dt { float: left; width: 160px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; } .dl-horizontal dd { margin-left: 180px; } } abbr[title], abbr[data-original-title] { cursor: help; border-bottom: 1px dotted #777; } .initialism { font-size: 90%; text-transform: uppercase; } blockquote { padding: 10px 20px; margin: 0 0 20px; font-size: 17.5px; border-left: 5px solid #eee; } blockquote p:last-child, blockquote ul:last-child, blockquote ol:last-child { margin-bottom: 0; } blockquote footer, blockquote small, blockquote .small { display: block; font-size: 80%; line-height: 1.42857143; color: #777; } blockquote footer:before, blockquote small:before, blockquote .small:before { content: '\2014 \00A0'; } .blockquote-reverse, blockquote.pull-right { padding-right: 15px; padding-left: 0; text-align: right; border-right: 5px solid #eee; border-left: 0; } .blockquote-reverse footer:before, blockquote.pull-right footer:before, .blockquote-reverse small:before, blockquote.pull-right small:before, .blockquote-reverse .small:before, blockquote.pull-right .small:before { content: ''; } .blockquote-reverse footer:after, blockquote.pull-right footer:after, .blockquote-reverse small:after, blockquote.pull-right small:after, .blockquote-reverse .small:after, blockquote.pull-right .small:after { content: '\00A0 \2014'; } address { margin-bottom: 20px; font-style: normal; line-height: 1.42857143; } code, kbd, pre, samp { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; border-radius: 4px; } kbd { padding: 2px 4px; font-size: 90%; color: #fff; background-color: #333; border-radius: 3px; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); } kbd kbd { padding: 0; font-size: 100%; font-weight: bold; -webkit-box-shadow: none; box-shadow: none; } pre { display: block; padding: 9.5px; margin: 0 0 10px; font-size: 13px; line-height: 1.42857143; color: #333; word-break: break-all; word-wrap: break-word; background-color: #f5f5f5; border: 1px solid #ccc; border-radius: 4px; } pre code { padding: 0; font-size: inherit; color: inherit; white-space: pre-wrap; background-color: transparent; border-radius: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } .container { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } @media (min-width: 768px) { .container { width: 750px; } } @media (min-width: 992px) { .container { width: 970px; } } @media (min-width: 1200px) { .container { width: 1170px; } } .container-fluid { padding-right: 15px; padding-left: 15px; margin-right: auto; margin-left: auto; } .row { margin-right: -15px; margin-left: -15px; } .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { position: relative; min-height: 1px; padding-right: 15px; padding-left: 15px; } .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { float: left; } .col-xs-12 { width: 100%; } .col-xs-11 { width: 91.66666667%; } .col-xs-10 { width: 83.33333333%; } .col-xs-9 { width: 75%; } .col-xs-8 { width: 66.66666667%; } .col-xs-7 { width: 58.33333333%; } .col-xs-6 { width: 50%; } .col-xs-5 { width: 41.66666667%; } .col-xs-4 { width: 33.33333333%; } .col-xs-3 { width: 25%; } .col-xs-2 { width: 16.66666667%; } .col-xs-1 { width: 8.33333333%; } .col-xs-pull-12 { right: 100%; } .col-xs-pull-11 { right: 91.66666667%; } .col-xs-pull-10 { right: 83.33333333%; } .col-xs-pull-9 { right: 75%; } .col-xs-pull-8 { right: 66.66666667%; } .col-xs-pull-7 { right: 58.33333333%; } .col-xs-pull-6 { right: 50%; } .col-xs-pull-5 { right: 41.66666667%; } .col-xs-pull-4 { right: 33.33333333%; } .col-xs-pull-3 { right: 25%; } .col-xs-pull-2 { right: 16.66666667%; } .col-xs-pull-1 { right: 8.33333333%; } .col-xs-pull-0 { right: auto; } .col-xs-push-12 { left: 100%; } .col-xs-push-11 { left: 91.66666667%; } .col-xs-push-10 { left: 83.33333333%; } .col-xs-push-9 { left: 75%; } .col-xs-push-8 { left: 66.66666667%; } .col-xs-push-7 { left: 58.33333333%; } .col-xs-push-6 { left: 50%; } .col-xs-push-5 { left: 41.66666667%; } .col-xs-push-4 { left: 33.33333333%; } .col-xs-push-3 { left: 25%; } .col-xs-push-2 { left: 16.66666667%; } .col-xs-push-1 { left: 8.33333333%; } .col-xs-push-0 { left: auto; } .col-xs-offset-12 { margin-left: 100%; } .col-xs-offset-11 { margin-left: 91.66666667%; } .col-xs-offset-10 { margin-left: 83.33333333%; } .col-xs-offset-9 { margin-left: 75%; } .col-xs-offset-8 { margin-left: 66.66666667%; } .col-xs-offset-7 { margin-left: 58.33333333%; } .col-xs-offset-6 { margin-left: 50%; } .col-xs-offset-5 { margin-left: 41.66666667%; } .col-xs-offset-4 { margin-left: 33.33333333%; } .col-xs-offset-3 { margin-left: 25%; } .col-xs-offset-2 { margin-left: 16.66666667%; } .col-xs-offset-1 { margin-left: 8.33333333%; } .col-xs-offset-0 { margin-left: 0; } @media (min-width: 768px) { .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { float: left; } .col-sm-12 { width: 100%; } .col-sm-11 { width: 91.66666667%; } .col-sm-10 { width: 83.33333333%; } .col-sm-9 { width: 75%; } .col-sm-8 { width: 66.66666667%; } .col-sm-7 { width: 58.33333333%; } .col-sm-6 { width: 50%; } .col-sm-5 { width: 41.66666667%; } .col-sm-4 { width: 33.33333333%; } .col-sm-3 { width: 25%; } .col-sm-2 { width: 16.66666667%; } .col-sm-1 { width: 8.33333333%; } .col-sm-pull-12 { right: 100%; } .col-sm-pull-11 { right: 91.66666667%; } .col-sm-pull-10 { right: 83.33333333%; } .col-sm-pull-9 { right: 75%; } .col-sm-pull-8 { right: 66.66666667%; } .col-sm-pull-7 { right: 58.33333333%; } .col-sm-pull-6 { right: 50%; } .col-sm-pull-5 { right: 41.66666667%; } .col-sm-pull-4 { right: 33.33333333%; } .col-sm-pull-3 { right: 25%; } .col-sm-pull-2 { right: 16.66666667%; } .col-sm-pull-1 { right: 8.33333333%; } .col-sm-pull-0 { right: auto; } .col-sm-push-12 { left: 100%; } .col-sm-push-11 { left: 91.66666667%; } .col-sm-push-10 { left: 83.33333333%; } .col-sm-push-9 { left: 75%; } .col-sm-push-8 { left: 66.66666667%; } .col-sm-push-7 { left: 58.33333333%; } .col-sm-push-6 { left: 50%; } .col-sm-push-5 { left: 41.66666667%; } .col-sm-push-4 { left: 33.33333333%; } .col-sm-push-3 { left: 25%; } .col-sm-push-2 { left: 16.66666667%; } .col-sm-push-1 { left: 8.33333333%; } .col-sm-push-0 { left: auto; } .col-sm-offset-12 { margin-left: 100%; } .col-sm-offset-11 { margin-left: 91.66666667%; } .col-sm-offset-10 { margin-left: 83.33333333%; } .col-sm-offset-9 { margin-left: 75%; } .col-sm-offset-8 { margin-left: 66.66666667%; } .col-sm-offset-7 { margin-left: 58.33333333%; } .col-sm-offset-6 { margin-left: 50%; } .col-sm-offset-5 { margin-left: 41.66666667%; } .col-sm-offset-4 { margin-left: 33.33333333%; } .col-sm-offset-3 { margin-left: 25%; } .col-sm-offset-2 { margin-left: 16.66666667%; } .col-sm-offset-1 { margin-left: 8.33333333%; } .col-sm-offset-0 { margin-left: 0; } } @media (min-width: 992px) { .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { float: left; } .col-md-12 { width: 100%; } .col-md-11 { width: 91.66666667%; } .col-md-10 { width: 83.33333333%; } .col-md-9 { width: 75%; } .col-md-8 { width: 66.66666667%; } .col-md-7 { width: 58.33333333%; } .col-md-6 { width: 50%; } .col-md-5 { width: 41.66666667%; } .col-md-4 { width: 33.33333333%; } .col-md-3 { width: 25%; } .col-md-2 { width: 16.66666667%; } .col-md-1 { width: 8.33333333%; } .col-md-pull-12 { right: 100%; } .col-md-pull-11 { right: 91.66666667%; } .col-md-pull-10 { right: 83.33333333%; } .col-md-pull-9 { right: 75%; } .col-md-pull-8 { right: 66.66666667%; } .col-md-pull-7 { right: 58.33333333%; } .col-md-pull-6 { right: 50%; } .col-md-pull-5 { right: 41.66666667%; } .col-md-pull-4 { right: 33.33333333%; } .col-md-pull-3 { right: 25%; } .col-md-pull-2 { right: 16.66666667%; } .col-md-pull-1 { right: 8.33333333%; } .col-md-pull-0 { right: auto; } .col-md-push-12 { left: 100%; } .col-md-push-11 { left: 91.66666667%; } .col-md-push-10 { left: 83.33333333%; } .col-md-push-9 { left: 75%; } .col-md-push-8 { left: 66.66666667%; } .col-md-push-7 { left: 58.33333333%; } .col-md-push-6 { left: 50%; } .col-md-push-5 { left: 41.66666667%; } .col-md-push-4 { left: 33.33333333%; } .col-md-push-3 { left: 25%; } .col-md-push-2 { left: 16.66666667%; } .col-md-push-1 { left: 8.33333333%; } .col-md-push-0 { left: auto; } .col-md-offset-12 { margin-left: 100%; } .col-md-offset-11 { margin-left: 91.66666667%; } .col-md-offset-10 { margin-left: 83.33333333%; } .col-md-offset-9 { margin-left: 75%; } .col-md-offset-8 { margin-left: 66.66666667%; } .col-md-offset-7 { margin-left: 58.33333333%; } .col-md-offset-6 { margin-left: 50%; } .col-md-offset-5 { margin-left: 41.66666667%; } .col-md-offset-4 { margin-left: 33.33333333%; } .col-md-offset-3 { margin-left: 25%; } .col-md-offset-2 { margin-left: 16.66666667%; } .col-md-offset-1 { margin-left: 8.33333333%; } .col-md-offset-0 { margin-left: 0; } } @media (min-width: 1200px) { .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { float: left; } .col-lg-12 { width: 100%; } .col-lg-11 { width: 91.66666667%; } .col-lg-10 { width: 83.33333333%; } .col-lg-9 { width: 75%; } .col-lg-8 { width: 66.66666667%; } .col-lg-7 { width: 58.33333333%; } .col-lg-6 { width: 50%; } .col-lg-5 { width: 41.66666667%; } .col-lg-4 { width: 33.33333333%; } .col-lg-3 { width: 25%; } .col-lg-2 { width: 16.66666667%; } .col-lg-1 { width: 8.33333333%; } .col-lg-pull-12 { right: 100%; } .col-lg-pull-11 { right: 91.66666667%; } .col-lg-pull-10 { right: 83.33333333%; } .col-lg-pull-9 { right: 75%; } .col-lg-pull-8 { right: 66.66666667%; } .col-lg-pull-7 { right: 58.33333333%; } .col-lg-pull-6 { right: 50%; } .col-lg-pull-5 { right: 41.66666667%; } .col-lg-pull-4 { right: 33.33333333%; } .col-lg-pull-3 { right: 25%; } .col-lg-pull-2 { right: 16.66666667%; } .col-lg-pull-1 { right: 8.33333333%; } .col-lg-pull-0 { right: auto; } .col-lg-push-12 { left: 100%; } .col-lg-push-11 { left: 91.66666667%; } .col-lg-push-10 { left: 83.33333333%; } .col-lg-push-9 { left: 75%; } .col-lg-push-8 { left: 66.66666667%; } .col-lg-push-7 { left: 58.33333333%; } .col-lg-push-6 { left: 50%; } .col-lg-push-5 { left: 41.66666667%; } .col-lg-push-4 { left: 33.33333333%; } .col-lg-push-3 { left: 25%; } .col-lg-push-2 { left: 16.66666667%; } .col-lg-push-1 { left: 8.33333333%; } .col-lg-push-0 { left: auto; } .col-lg-offset-12 { margin-left: 100%; } .col-lg-offset-11 { margin-left: 91.66666667%; } .col-lg-offset-10 { margin-left: 83.33333333%; } .col-lg-offset-9 { margin-left: 75%; } .col-lg-offset-8 { margin-left: 66.66666667%; } .col-lg-offset-7 { margin-left: 58.33333333%; } .col-lg-offset-6 { margin-left: 50%; } .col-lg-offset-5 { margin-left: 41.66666667%; } .col-lg-offset-4 { margin-left: 33.33333333%; } .col-lg-offset-3 { margin-left: 25%; } .col-lg-offset-2 { margin-left: 16.66666667%; } .col-lg-offset-1 { margin-left: 8.33333333%; } .col-lg-offset-0 { margin-left: 0; } } table { background-color: transparent; } caption { padding-top: 8px; padding-bottom: 8px; color: #777; text-align: left; } th { text-align: left; } .table { width: 100%; max-width: 100%; margin-bottom: 20px; } .table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th, .table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td { padding: 8px; line-height: 1.42857143; vertical-align: top; border-top: 1px solid #ddd; } .table > thead > tr > th { vertical-align: bottom; border-bottom: 2px solid #ddd; } .table > caption + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > th, .table > thead:first-child > tr:first-child > th, .table > caption + thead > tr:first-child > td, .table > colgroup + thead > tr:first-child > td, .table > thead:first-child > tr:first-child > td { border-top: 0; } .table > tbody + tbody { border-top: 2px solid #ddd; } .table .table { background-color: #fff; } .table-condensed > thead > tr > th, .table-condensed > tbody > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > thead > tr > td, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > td { padding: 5px; } .table-bordered { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > thead > tr > td { border-bottom-width: 2px; } .table-striped > tbody > tr:nth-of-type(odd) { background-color: #f9f9f9; } .table-hover > tbody > tr:hover { background-color: #f5f5f5; } table col[class*="col-"] { position: static; display: table-column; float: none; } table td[class*="col-"], table th[class*="col-"] { position: static; display: table-cell; float: none; } .table > thead > tr > td.active, .table > tbody > tr > td.active, .table > tfoot > tr > td.active, .table > thead > tr > th.active, .table > tbody > tr > th.active, .table > tfoot > tr > th.active, .table > thead > tr.active > td, .table > tbody > tr.active > td, .table > tfoot > tr.active > td, .table > thead > tr.active > th, .table > tbody > tr.active > th, .table > tfoot > tr.active > th { background-color: #f5f5f5; } .table-hover > tbody > tr > td.active:hover, .table-hover > tbody > tr > th.active:hover, .table-hover > tbody > tr.active:hover > td, .table-hover > tbody > tr:hover > .active, .table-hover > tbody > tr.active:hover > th { background-color: #e8e8e8; } .table > thead > tr > td.success, .table > tbody > tr > td.success, .table > tfoot > tr > td.success, .table > thead > tr > th.success, .table > tbody > tr > th.success, .table > tfoot > tr > th.success, .table > thead > tr.success > td, .table > tbody > tr.success > td, .table > tfoot > tr.success > td, .table > thead > tr.success > th, .table > tbody > tr.success > th, .table > tfoot > tr.success > th { background-color: #dff0d8; } .table-hover > tbody > tr > td.success:hover, .table-hover > tbody > tr > th.success:hover, .table-hover > tbody > tr.success:hover > td, .table-hover > tbody > tr:hover > .success, .table-hover > tbody > tr.success:hover > th { background-color: #d0e9c6; } .table > thead > tr > td.info, .table > tbody > tr > td.info, .table > tfoot > tr > td.info, .table > thead > tr > th.info, .table > tbody > tr > th.info, .table > tfoot > tr > th.info, .table > thead > tr.info > td, .table > tbody > tr.info > td, .table > tfoot > tr.info > td, .table > thead > tr.info > th, .table > tbody > tr.info > th, .table > tfoot > tr.info > th { background-color: #d9edf7; } .table-hover > tbody > tr > td.info:hover, .table-hover > tbody > tr > th.info:hover, .table-hover > tbody > tr.info:hover > td, .table-hover > tbody > tr:hover > .info, .table-hover > tbody > tr.info:hover > th { background-color: #c4e3f3; } .table > thead > tr > td.warning, .table > tbody > tr > td.warning, .table > tfoot > tr > td.warning, .table > thead > tr > th.warning, .table > tbody > tr > th.warning, .table > tfoot > tr > th.warning, .table > thead > tr.warning > td, .table > tbody > tr.warning > td, .table > tfoot > tr.warning > td, .table > thead > tr.warning > th, .table > tbody > tr.warning > th, .table > tfoot > tr.warning > th { background-color: #fcf8e3; } .table-hover > tbody > tr > td.warning:hover, .table-hover > tbody > tr > th.warning:hover, .table-hover > tbody > tr.warning:hover > td, .table-hover > tbody > tr:hover > .warning, .table-hover > tbody > tr.warning:hover > th { background-color: #faf2cc; } .table > thead > tr > td.danger, .table > tbody > tr > td.danger, .table > tfoot > tr > td.danger, .table > thead > tr > th.danger, .table > tbody > tr > th.danger, .table > tfoot > tr > th.danger, .table > thead > tr.danger > td, .table > tbody > tr.danger > td, .table > tfoot > tr.danger > td, .table > thead > tr.danger > th, .table > tbody > tr.danger > th, .table > tfoot > tr.danger > th { background-color: #f2dede; } .table-hover > tbody > tr > td.danger:hover, .table-hover > tbody > tr > th.danger:hover, .table-hover > tbody > tr.danger:hover > td, .table-hover > tbody > tr:hover > .danger, .table-hover > tbody > tr.danger:hover > th { background-color: #ebcccc; } .table-responsive { min-height: .01%; overflow-x: auto; } @media screen and (max-width: 767px) { .table-responsive { width: 100%; margin-bottom: 15px; overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; border: 1px solid #ddd; } .table-responsive > .table { margin-bottom: 0; } .table-responsive > .table > thead > tr > th, .table-responsive > .table > tbody > tr > th, .table-responsive > .table > tfoot > tr > th, .table-responsive > .table > thead > tr > td, .table-responsive > .table > tbody > tr > td, .table-responsive > .table > tfoot > tr > td { white-space: nowrap; } .table-responsive > .table-bordered { border: 0; } .table-responsive > .table-bordered > thead > tr > th:first-child, .table-responsive > .table-bordered > tbody > tr > th:first-child, .table-responsive > .table-bordered > tfoot > tr > th:first-child, .table-responsive > .table-bordered > thead > tr > td:first-child, .table-responsive > .table-bordered > tbody > tr > td:first-child, .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .table-responsive > .table-bordered > thead > tr > th:last-child, .table-responsive > .table-bordered > tbody > tr > th:last-child, .table-responsive > .table-bordered > tfoot > tr > th:last-child, .table-responsive > .table-bordered > thead > tr > td:last-child, .table-responsive > .table-bordered > tbody > tr > td:last-child, .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .table-responsive > .table-bordered > tbody > tr:last-child > th, .table-responsive > .table-bordered > tfoot > tr:last-child > th, .table-responsive > .table-bordered > tbody > tr:last-child > td, .table-responsive > .table-bordered > tfoot > tr:last-child > td { border-bottom: 0; } } fieldset { min-width: 0; padding: 0; margin: 0; border: 0; } legend { display: block; width: 100%; padding: 0; margin-bottom: 20px; font-size: 21px; line-height: inherit; color: #333; border: 0; border-bottom: 1px solid #e5e5e5; } label { display: inline-block; max-width: 100%; margin-bottom: 5px; font-weight: bold; } input[type="search"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } input[type="radio"], input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; line-height: normal; } input[type="file"] { display: block; } input[type="range"] { display: block; width: 100%; } select[multiple], select[size] { height: auto; } input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } output { display: block; padding-top: 7px; font-size: 14px; line-height: 1.42857143; color: #555; } .form-control { display: block; width: 100%; height: 34px; padding: 6px 12px; font-size: 14px; line-height: 1.42857143; color: #555; background-color: #fff; background-image: none; border: 1px solid #ccc; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } .form-control:focus { border-color: #66afe9; outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); } .form-control::-moz-placeholder { color: #999; opacity: 1; } .form-control:-ms-input-placeholder { color: #999; } .form-control::-webkit-input-placeholder { color: #999; } .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { cursor: not-allowed; background-color: #eee; opacity: 1; } textarea.form-control { height: auto; } input[type="search"] { -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"] { line-height: 34px; } input[type="date"].input-sm, input[type="time"].input-sm, input[type="datetime-local"].input-sm, input[type="month"].input-sm, .input-group-sm input[type="date"], .input-group-sm input[type="time"], .input-group-sm input[type="datetime-local"], .input-group-sm input[type="month"] { line-height: 30px; } input[type="date"].input-lg, input[type="time"].input-lg, input[type="datetime-local"].input-lg, input[type="month"].input-lg, .input-group-lg input[type="date"], .input-group-lg input[type="time"], .input-group-lg input[type="datetime-local"], .input-group-lg input[type="month"] { line-height: 46px; } } .form-group { margin-bottom: 15px; } .radio, .checkbox { position: relative; display: block; margin-top: 10px; margin-bottom: 10px; } .radio label, .checkbox label { min-height: 20px; padding-left: 20px; margin-bottom: 0; font-weight: normal; cursor: pointer; } .radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { position: absolute; margin-top: 4px \9; margin-left: -20px; } .radio + .radio, .checkbox + .checkbox { margin-top: -5px; } .radio-inline, .checkbox-inline { display: inline-block; padding-left: 20px; margin-bottom: 0; font-weight: normal; vertical-align: middle; cursor: pointer; } .radio-inline + .radio-inline, .checkbox-inline + .checkbox-inline { margin-top: 0; margin-left: 10px; } input[type="radio"][disabled], input[type="checkbox"][disabled], input[type="radio"].disabled, input[type="checkbox"].disabled, fieldset[disabled] input[type="radio"], fieldset[disabled] input[type="checkbox"] { cursor: not-allowed; } .radio-inline.disabled, .checkbox-inline.disabled, fieldset[disabled] .radio-inline, fieldset[disabled] .checkbox-inline { cursor: not-allowed; } .radio.disabled label, .checkbox.disabled label, fieldset[disabled] .radio label, fieldset[disabled] .checkbox label { cursor: not-allowed; } .form-control-static { padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; } .form-control-static.input-lg, .form-control-static.input-sm { padding-right: 0; padding-left: 0; } .input-sm { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.input-sm { height: 30px; line-height: 30px; } textarea.input-sm, select[multiple].input-sm { height: auto; } .form-group-sm .form-control { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.form-group-sm .form-control { height: 30px; line-height: 30px; } textarea.form-group-sm .form-control, select[multiple].form-group-sm .form-control { height: auto; } .form-group-sm .form-control-static { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; } .input-lg { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.input-lg { height: 46px; line-height: 46px; } textarea.input-lg, select[multiple].input-lg { height: auto; } .form-group-lg .form-control { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.form-group-lg .form-control { height: 46px; line-height: 46px; } textarea.form-group-lg .form-control, select[multiple].form-group-lg .form-control { height: auto; } .form-group-lg .form-control-static { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; } .has-feedback { position: relative; } .has-feedback .form-control { padding-right: 42.5px; } .form-control-feedback { position: absolute; top: 0; right: 0; z-index: 2; display: block; width: 34px; height: 34px; line-height: 34px; text-align: center; pointer-events: none; } .input-lg + .form-control-feedback { width: 46px; height: 46px; line-height: 46px; } .input-sm + .form-control-feedback { width: 30px; height: 30px; line-height: 30px; } .has-success .help-block, .has-success .control-label, .has-success .radio, .has-success .checkbox, .has-success .radio-inline, .has-success .checkbox-inline, .has-success.radio label, .has-success.checkbox label, .has-success.radio-inline label, .has-success.checkbox-inline label { color: #3c763d; } .has-success .form-control { border-color: #3c763d; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-success .form-control:focus { border-color: #2b542c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; } .has-success .input-group-addon { color: #3c763d; background-color: #dff0d8; border-color: #3c763d; } .has-success .form-control-feedback { color: #3c763d; } .has-warning .help-block, .has-warning .control-label, .has-warning .radio, .has-warning .checkbox, .has-warning .radio-inline, .has-warning .checkbox-inline, .has-warning.radio label, .has-warning.checkbox label, .has-warning.radio-inline label, .has-warning.checkbox-inline label { color: #8a6d3b; } .has-warning .form-control { border-color: #8a6d3b; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-warning .form-control:focus { border-color: #66512c; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; } .has-warning .input-group-addon { color: #8a6d3b; background-color: #fcf8e3; border-color: #8a6d3b; } .has-warning .form-control-feedback { color: #8a6d3b; } .has-error .help-block, .has-error .control-label, .has-error .radio, .has-error .checkbox, .has-error .radio-inline, .has-error .checkbox-inline, .has-error.radio label, .has-error.checkbox label, .has-error.radio-inline label, .has-error.checkbox-inline label { color: #a94442; } .has-error .form-control { border-color: #a94442; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); } .has-error .form-control:focus { border-color: #843534; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; } .has-error .input-group-addon { color: #a94442; background-color: #f2dede; border-color: #a94442; } .has-error .form-control-feedback { color: #a94442; } .has-feedback label ~ .form-control-feedback { top: 25px; } .has-feedback label.sr-only ~ .form-control-feedback { top: 0; } .help-block { display: block; margin-top: 5px; margin-bottom: 10px; color: #737373; } @media (min-width: 768px) { .form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; } .form-inline .form-control-static { display: inline-block; } .form-inline .input-group { display: inline-table; vertical-align: middle; } .form-inline .input-group .input-group-addon, .form-inline .input-group .input-group-btn, .form-inline .input-group .form-control { width: auto; } .form-inline .input-group > .form-control { width: 100%; } .form-inline .control-label { margin-bottom: 0; vertical-align: middle; } .form-inline .radio, .form-inline .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .form-inline .radio label, .form-inline .checkbox label { padding-left: 0; } .form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .form-inline .has-feedback .form-control-feedback { top: 0; } } .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { padding-top: 7px; margin-top: 0; margin-bottom: 0; } .form-horizontal .radio, .form-horizontal .checkbox { min-height: 27px; } .form-horizontal .form-group { margin-right: -15px; margin-left: -15px; } @media (min-width: 768px) { .form-horizontal .control-label { padding-top: 7px; margin-bottom: 0; text-align: right; } } .form-horizontal .has-feedback .form-control-feedback { right: 15px; } @media (min-width: 768px) { .form-horizontal .form-group-lg .control-label { padding-top: 14.333333px; } } @media (min-width: 768px) { .form-horizontal .form-group-sm .control-label { padding-top: 6px; } } .btn { display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 14px; font-weight: normal; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-image: none; border: 1px solid transparent; border-radius: 4px; } .btn:focus, .btn:active:focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn.active.focus { outline: thin dotted; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .btn:hover, .btn:focus, .btn.focus { color: #333; text-decoration: none; } .btn:active, .btn.active { background-image: none; outline: 0; -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn.disabled, .btn[disabled], fieldset[disabled] .btn { pointer-events: none; cursor: not-allowed; filter: alpha(opacity=65); -webkit-box-shadow: none; box-shadow: none; opacity: .65; } .btn-default { color: #333; background-color: #fff; border-color: #ccc; } .btn-default:hover, .btn-default:focus, .btn-default.focus, .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { color: #333; background-color: #e6e6e6; border-color: #adadad; } .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { background-image: none; } .btn-default.disabled, .btn-default[disabled], fieldset[disabled] .btn-default, .btn-default.disabled:hover, .btn-default[disabled]:hover, fieldset[disabled] .btn-default:hover, .btn-default.disabled:focus, .btn-default[disabled]:focus, fieldset[disabled] .btn-default:focus, .btn-default.disabled.focus, .btn-default[disabled].focus, fieldset[disabled] .btn-default.focus, .btn-default.disabled:active, .btn-default[disabled]:active, fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { background-color: #fff; border-color: #ccc; } .btn-default .badge { color: #fff; background-color: #333; } .btn-primary { color: #fff; background-color: #337ab7; border-color: #2e6da4; } .btn-primary:hover, .btn-primary:focus, .btn-primary.focus, .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { color: #fff; background-color: #286090; border-color: #204d74; } .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { background-image: none; } .btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled.focus, .btn-primary[disabled].focus, fieldset[disabled] .btn-primary.focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { background-color: #337ab7; border-color: #2e6da4; } .btn-primary .badge { color: #337ab7; background-color: #fff; } .btn-success { color: #fff; background-color: #5cb85c; border-color: #4cae4c; } .btn-success:hover, .btn-success:focus, .btn-success.focus, .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { color: #fff; background-color: #449d44; border-color: #398439; } .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { background-image: none; } .btn-success.disabled, .btn-success[disabled], fieldset[disabled] .btn-success, .btn-success.disabled:hover, .btn-success[disabled]:hover, fieldset[disabled] .btn-success:hover, .btn-success.disabled:focus, .btn-success[disabled]:focus, fieldset[disabled] .btn-success:focus, .btn-success.disabled.focus, .btn-success[disabled].focus, fieldset[disabled] .btn-success.focus, .btn-success.disabled:active, .btn-success[disabled]:active, fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { background-color: #5cb85c; border-color: #4cae4c; } .btn-success .badge { color: #5cb85c; background-color: #fff; } .btn-info { color: #fff; background-color: #5bc0de; border-color: #46b8da; } .btn-info:hover, .btn-info:focus, .btn-info.focus, .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { color: #fff; background-color: #31b0d5; border-color: #269abc; } .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { background-image: none; } .btn-info.disabled, .btn-info[disabled], fieldset[disabled] .btn-info, .btn-info.disabled:hover, .btn-info[disabled]:hover, fieldset[disabled] .btn-info:hover, .btn-info.disabled:focus, .btn-info[disabled]:focus, fieldset[disabled] .btn-info:focus, .btn-info.disabled.focus, .btn-info[disabled].focus, fieldset[disabled] .btn-info.focus, .btn-info.disabled:active, .btn-info[disabled]:active, fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { background-color: #5bc0de; border-color: #46b8da; } .btn-info .badge { color: #5bc0de; background-color: #fff; } .btn-warning { color: #fff; background-color: #f0ad4e; border-color: #eea236; } .btn-warning:hover, .btn-warning:focus, .btn-warning.focus, .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { color: #fff; background-color: #ec971f; border-color: #d58512; } .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { background-image: none; } .btn-warning.disabled, .btn-warning[disabled], fieldset[disabled] .btn-warning, .btn-warning.disabled:hover, .btn-warning[disabled]:hover, fieldset[disabled] .btn-warning:hover, .btn-warning.disabled:focus, .btn-warning[disabled]:focus, fieldset[disabled] .btn-warning:focus, .btn-warning.disabled.focus, .btn-warning[disabled].focus, fieldset[disabled] .btn-warning.focus, .btn-warning.disabled:active, .btn-warning[disabled]:active, fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { background-color: #f0ad4e; border-color: #eea236; } .btn-warning .badge { color: #f0ad4e; background-color: #fff; } .btn-danger { color: #fff; background-color: #d9534f; border-color: #d43f3a; } .btn-danger:hover, .btn-danger:focus, .btn-danger.focus, .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { color: #fff; background-color: #c9302c; border-color: #ac2925; } .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { background-image: none; } .btn-danger.disabled, .btn-danger[disabled], fieldset[disabled] .btn-danger, .btn-danger.disabled:hover, .btn-danger[disabled]:hover, fieldset[disabled] .btn-danger:hover, .btn-danger.disabled:focus, .btn-danger[disabled]:focus, fieldset[disabled] .btn-danger:focus, .btn-danger.disabled.focus, .btn-danger[disabled].focus, fieldset[disabled] .btn-danger.focus, .btn-danger.disabled:active, .btn-danger[disabled]:active, fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { background-color: #d9534f; border-color: #d43f3a; } .btn-danger .badge { color: #d9534f; background-color: #fff; } .btn-link { font-weight: normal; color: #337ab7; border-radius: 0; } .btn-link, .btn-link:active, .btn-link.active, .btn-link[disabled], fieldset[disabled] .btn-link { background-color: transparent; -webkit-box-shadow: none; box-shadow: none; } .btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { border-color: transparent; } .btn-link:hover, .btn-link:focus { color: #23527c; text-decoration: underline; background-color: transparent; } .btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { color: #777; text-decoration: none; } .btn-lg, .btn-group-lg > .btn { padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } .btn-sm, .btn-group-sm > .btn { padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } .btn-xs, .btn-group-xs > .btn { padding: 1px 5px; font-size: 12px; line-height: 1.5; border-radius: 3px; } .btn-block { display: block; width: 100%; } .btn-block + .btn-block { margin-top: 5px; } input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { width: 100%; } .fade { opacity: 0; -webkit-transition: opacity .15s linear; -o-transition: opacity .15s linear; transition: opacity .15s linear; } .fade.in { opacity: 1; } .collapse { display: none; visibility: hidden; } .collapse.in { display: block; visibility: visible; } tr.collapse.in { display: table-row; } tbody.collapse.in { display: table-row-group; } .collapsing { position: relative; height: 0; overflow: hidden; -webkit-transition-timing-function: ease; -o-transition-timing-function: ease; transition-timing-function: ease; -webkit-transition-duration: .35s; -o-transition-duration: .35s; transition-duration: .35s; -webkit-transition-property: height, visibility; -o-transition-property: height, visibility; transition-property: height, visibility; } .caret { display: inline-block; width: 0; height: 0; margin-left: 2px; vertical-align: middle; border-top: 4px solid; border-right: 4px solid transparent; border-left: 4px solid transparent; } .dropup, .dropdown { position: relative; } .dropdown-toggle:focus { outline: 0; } .dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; font-size: 14px; text-align: left; list-style: none; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, .15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); box-shadow: 0 6px 12px rgba(0, 0, 0, .175); } .dropdown-menu.pull-right { right: 0; left: auto; } .dropdown-menu .divider { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .dropdown-menu > li > a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.42857143; color: #333; white-space: nowrap; } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { color: #262626; text-decoration: none; background-color: #f5f5f5; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { color: #fff; text-decoration: none; background-color: #337ab7; outline: 0; } .dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { color: #777; } .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { text-decoration: none; cursor: not-allowed; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); } .open > .dropdown-menu { display: block; } .open > a { outline: 0; } .dropdown-menu-right { right: 0; left: auto; } .dropdown-menu-left { right: auto; left: 0; } .dropdown-header { display: block; padding: 3px 20px; font-size: 12px; line-height: 1.42857143; color: #777; white-space: nowrap; } .dropdown-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 990; } .pull-right > .dropdown-menu { right: 0; left: auto; } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { content: ""; border-top: 0; border-bottom: 4px solid; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 2px; } @media (min-width: 768px) { .navbar-right .dropdown-menu { right: 0; left: auto; } .navbar-right .dropdown-menu-left { right: auto; left: 0; } } .btn-group, .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle; } .btn-group > .btn, .btn-group-vertical > .btn { position: relative; float: left; } .btn-group > .btn:hover, .btn-group-vertical > .btn:hover, .btn-group > .btn:focus, .btn-group-vertical > .btn:focus, .btn-group > .btn:active, .btn-group-vertical > .btn:active, .btn-group > .btn.active, .btn-group-vertical > .btn.active { z-index: 2; } .btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group { margin-left: -1px; } .btn-toolbar { margin-left: -5px; } .btn-toolbar .btn-group, .btn-toolbar .input-group { float: left; } .btn-toolbar > .btn, .btn-toolbar > .btn-group, .btn-toolbar > .input-group { margin-left: 5px; } .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0; } .btn-group > .btn:first-child { margin-left: 0; } .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-top-right-radius: 0; border-bottom-right-radius: 0; } .btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; } .btn-group > .btn-group { float: left; } .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-top-right-radius: 0; border-bottom-right-radius: 0; } .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-left-radius: 0; border-bottom-left-radius: 0; } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0; } .btn-group > .btn + .dropdown-toggle { padding-right: 8px; padding-left: 8px; } .btn-group > .btn-lg + .dropdown-toggle { padding-right: 12px; padding-left: 12px; } .btn-group.open .dropdown-toggle { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); } .btn-group.open .dropdown-toggle.btn-link { -webkit-box-shadow: none; box-shadow: none; } .btn .caret { margin-left: 0; } .btn-lg .caret { border-width: 5px 5px 0; border-bottom-width: 0; } .dropup .btn-lg .caret { border-width: 0 5px 5px; } .btn-group-vertical > .btn, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn { display: block; float: none; width: 100%; max-width: 100%; } .btn-group-vertical > .btn-group > .btn { float: none; } .btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0; } .btn-group-vertical > .btn:not(:first-child):not(:last-child) { border-radius: 0; } .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-left-radius: 4px; } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-left-radius: 0; border-top-right-radius: 0; } .btn-group-justified { display: table; width: 100%; table-layout: fixed; border-collapse: separate; } .btn-group-justified > .btn, .btn-group-justified > .btn-group { display: table-cell; float: none; width: 1%; } .btn-group-justified > .btn-group .btn { width: 100%; } .btn-group-justified > .btn-group .dropdown-menu { left: auto; } [data-toggle="buttons"] > .btn input[type="radio"], [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], [data-toggle="buttons"] > .btn input[type="checkbox"], [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; } .input-group { position: relative; display: table; border-collapse: separate; } .input-group[class*="col-"] { float: none; padding-right: 0; padding-left: 0; } .input-group .form-control { position: relative; z-index: 2; float: left; width: 100%; margin-bottom: 0; } .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn { height: 46px; padding: 10px 16px; font-size: 18px; line-height: 1.3333333; border-radius: 6px; } select.input-group-lg > .form-control, select.input-group-lg > .input-group-addon, select.input-group-lg > .input-group-btn > .btn { height: 46px; line-height: 46px; } textarea.input-group-lg > .form-control, textarea.input-group-lg > .input-group-addon, textarea.input-group-lg > .input-group-btn > .btn, select[multiple].input-group-lg > .form-control, select[multiple].input-group-lg > .input-group-addon, select[multiple].input-group-lg > .input-group-btn > .btn { height: auto; } .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px; } select.input-group-sm > .form-control, select.input-group-sm > .input-group-addon, select.input-group-sm > .input-group-btn > .btn { height: 30px; line-height: 30px; } textarea.input-group-sm > .form-control, textarea.input-group-sm > .input-group-addon, textarea.input-group-sm > .input-group-btn > .btn, select[multiple].input-group-sm > .form-control, select[multiple].input-group-sm > .input-group-addon, select[multiple].input-group-sm > .input-group-btn > .btn { height: auto; } .input-group-addon, .input-group-btn, .input-group .form-control { display: table-cell; } .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) { border-radius: 0; } .input-group-addon, .input-group-btn { width: 1%; white-space: nowrap; vertical-align: middle; } .input-group-addon { padding: 6px 12px; font-size: 14px; font-weight: normal; line-height: 1; color: #555; text-align: center; background-color: #eee; border: 1px solid #ccc; border-radius: 4px; } .input-group-addon.input-sm { padding: 5px 10px; font-size: 12px; border-radius: 3px; } .input-group-addon.input-lg { padding: 10px 16px; font-size: 18px; border-radius: 6px; } .input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { margin-top: 0; } .input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group > .btn, .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { border-top-right-radius: 0; border-bottom-right-radius: 0; } .input-group-addon:first-child { border-right: 0; } .input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group > .btn, .input-group-btn:last-child > .dropdown-toggle, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { border-top-left-radius: 0; border-bottom-left-radius: 0; } .input-group-addon:last-child { border-left: 0; } .input-group-btn { position: relative; font-size: 0; white-space: nowrap; } .input-group-btn > .btn { position: relative; } .input-group-btn > .btn + .btn { margin-left: -1px; } .input-group-btn > .btn:hover, .input-group-btn > .btn:focus, .input-group-btn > .btn:active { z-index: 2; } .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group { margin-right: -1px; } .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group { margin-left: -1px; } .nav { padding-left: 0; margin-bottom: 0; list-style: none; } .nav > li { position: relative; display: block; } .nav > li > a { position: relative; display: block; padding: 10px 15px; } .nav > li > a:hover, .nav > li > a:focus { text-decoration: none; background-color: #eee; } .nav > li.disabled > a { color: #777; } .nav > li.disabled > a:hover, .nav > li.disabled > a:focus { color: #777; text-decoration: none; cursor: not-allowed; background-color: transparent; } .nav .open > a, .nav .open > a:hover, .nav .open > a:focus { background-color: #eee; border-color: #337ab7; } .nav .nav-divider { height: 1px; margin: 9px 0; overflow: hidden; background-color: #e5e5e5; } .nav > li > a > img { max-width: none; } .nav-tabs { border-bottom: 1px solid #ddd; } .nav-tabs > li { float: left; margin-bottom: -1px; } .nav-tabs > li > a { margin-right: 2px; line-height: 1.42857143; border: 1px solid transparent; border-radius: 4px 4px 0 0; } .nav-tabs > li > a:hover { border-color: #eee #eee #ddd; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { color: #555; cursor: default; background-color: #fff; border: 1px solid #ddd; border-bottom-color: transparent; } .nav-tabs.nav-justified { width: 100%; border-bottom: 0; } .nav-tabs.nav-justified > li { float: none; } .nav-tabs.nav-justified > li > a { margin-bottom: 5px; text-align: center; } .nav-tabs.nav-justified > .dropdown .dropdown-menu { top: auto; left: auto; } @media (min-width: 768px) { .nav-tabs.nav-justified > li { display: table-cell; width: 1%; } .nav-tabs.nav-justified > li > a { margin-bottom: 0; } } .nav-tabs.nav-justified > li > a { margin-right: 0; border-radius: 4px; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs.nav-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { border-bottom-color: #fff; } } .nav-pills > li { float: left; } .nav-pills > li > a { border-radius: 4px; } .nav-pills > li + li { margin-left: 2px; } .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { color: #fff; background-color: #337ab7; } .nav-stacked > li { float: none; } .nav-stacked > li + li { margin-top: 2px; margin-left: 0; } .nav-justified { width: 100%; } .nav-justified > li { float: none; } .nav-justified > li > a { margin-bottom: 5px; text-align: center; } .nav-justified > .dropdown .dropdown-menu { top: auto; left: auto; } @media (min-width: 768px) { .nav-justified > li { display: table-cell; width: 1%; } .nav-justified > li > a { margin-bottom: 0; } } .nav-tabs-justified { border-bottom: 0; } .nav-tabs-justified > li > a { margin-right: 0; border-radius: 4px; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { border: 1px solid #ddd; } @media (min-width: 768px) { .nav-tabs-justified > li > a { border-bottom: 1px solid #ddd; border-radius: 4px 4px 0 0; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { border-bottom-color: #fff; } } .tab-content > .tab-pane { display: none; visibility: hidden; } .tab-content > .active { display: block; visibility: visible; } .nav-tabs .dropdown-menu { margin-top: -1px; border-top-left-radius: 0; border-top-right-radius: 0; } .navbar { position: relative; min-height: 50px; margin-bottom: 20px; border: 1px solid transparent; } @media (min-width: 768px) { .navbar { border-radius: 4px; } } @media (min-width: 768px) { .navbar-header { float: left; } } .navbar-collapse { padding-right: 15px; padding-left: 15px; overflow-x: visible; -webkit-overflow-scrolling: touch; border-top: 1px solid transparent; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); } .navbar-collapse.in { overflow-y: auto; } @media (min-width: 768px) { .navbar-collapse { width: auto; border-top: 0; -webkit-box-shadow: none; box-shadow: none; } .navbar-collapse.collapse { display: block !important; height: auto !important; padding-bottom: 0; overflow: visible !important; visibility: visible !important; } .navbar-collapse.in { overflow-y: visible; } .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { padding-right: 0; padding-left: 0; } } .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 340px; } @media (max-device-width: 480px) and (orientation: landscape) { .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 200px; } } .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { margin-right: -15px; margin-left: -15px; } @media (min-width: 768px) { .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { margin-right: 0; margin-left: 0; } } .navbar-static-top { z-index: 1000; border-width: 0 0 1px; } @media (min-width: 768px) { .navbar-static-top { border-radius: 0; } } .navbar-fixed-top, .navbar-fixed-bottom { position: fixed; right: 0; left: 0; z-index: 1030; } @media (min-width: 768px) { .navbar-fixed-top, .navbar-fixed-bottom { border-radius: 0; } } .navbar-fixed-top { top: 0; border-width: 0 0 1px; } .navbar-fixed-bottom { bottom: 0; margin-bottom: 0; border-width: 1px 0 0; } .navbar-brand { float: left; height: 50px; padding: 15px 15px; font-size: 18px; line-height: 20px; } .navbar-brand:hover, .navbar-brand:focus { text-decoration: none; } .navbar-brand > img { display: block; } @media (min-width: 768px) { .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand { margin-left: -15px; } } .navbar-toggle { position: relative; float: right; padding: 9px 10px; margin-top: 8px; margin-right: 15px; margin-bottom: 8px; background-color: transparent; background-image: none; border: 1px solid transparent; border-radius: 4px; } .navbar-toggle:focus { outline: 0; } .navbar-toggle .icon-bar { display: block; width: 22px; height: 2px; border-radius: 1px; } .navbar-toggle .icon-bar + .icon-bar { margin-top: 4px; } @media (min-width: 768px) { .navbar-toggle { display: none; } } .navbar-nav { margin: 7.5px -15px; } .navbar-nav > li > a { padding-top: 10px; padding-bottom: 10px; line-height: 20px; } @media (max-width: 767px) { .navbar-nav .open .dropdown-menu { position: static; float: none; width: auto; margin-top: 0; background-color: transparent; border: 0; -webkit-box-shadow: none; box-shadow: none; } .navbar-nav .open .dropdown-menu > li > a, .navbar-nav .open .dropdown-menu .dropdown-header { padding: 5px 15px 5px 25px; } .navbar-nav .open .dropdown-menu > li > a { line-height: 20px; } .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-nav .open .dropdown-menu > li > a:focus { background-image: none; } } @media (min-width: 768px) { .navbar-nav { float: left; margin: 0; } .navbar-nav > li { float: left; } .navbar-nav > li > a { padding-top: 15px; padding-bottom: 15px; } } .navbar-form { padding: 10px 15px; margin-top: 8px; margin-right: -15px; margin-bottom: 8px; margin-left: -15px; border-top: 1px solid transparent; border-bottom: 1px solid transparent; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); } @media (min-width: 768px) { .navbar-form .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .navbar-form .form-control { display: inline-block; width: auto; vertical-align: middle; } .navbar-form .form-control-static { display: inline-block; } .navbar-form .input-group { display: inline-table; vertical-align: middle; } .navbar-form .input-group .input-group-addon, .navbar-form .input-group .input-group-btn, .navbar-form .input-group .form-control { width: auto; } .navbar-form .input-group > .form-control { width: 100%; } .navbar-form .control-label { margin-bottom: 0; vertical-align: middle; } .navbar-form .radio, .navbar-form .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .navbar-form .radio label, .navbar-form .checkbox label { padding-left: 0; } .navbar-form .radio input[type="radio"], .navbar-form .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .navbar-form .has-feedback .form-control-feedback { top: 0; } } @media (max-width: 767px) { .navbar-form .form-group { margin-bottom: 5px; } .navbar-form .form-group:last-child { margin-bottom: 0; } } @media (min-width: 768px) { .navbar-form { width: auto; padding-top: 0; padding-bottom: 0; margin-right: 0; margin-left: 0; border: 0; -webkit-box-shadow: none; box-shadow: none; } } .navbar-nav > li > .dropdown-menu { margin-top: 0; border-top-left-radius: 0; border-top-right-radius: 0; } .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { margin-bottom: 0; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .navbar-btn { margin-top: 8px; margin-bottom: 8px; } .navbar-btn.btn-sm { margin-top: 10px; margin-bottom: 10px; } .navbar-btn.btn-xs { margin-top: 14px; margin-bottom: 14px; } .navbar-text { margin-top: 15px; margin-bottom: 15px; } @media (min-width: 768px) { .navbar-text { float: left; margin-right: 15px; margin-left: 15px; } } @media (min-width: 768px) { .navbar-left { float: left !important; } .navbar-right { float: right !important; margin-right: -15px; } .navbar-right ~ .navbar-right { margin-right: 0; } } .navbar-default { background-color: #f8f8f8; border-color: #e7e7e7; } .navbar-default .navbar-brand { color: #777; } .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { color: #5e5e5e; background-color: transparent; } .navbar-default .navbar-text { color: #777; } .navbar-default .navbar-nav > li > a { color: #777; } .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { color: #333; background-color: transparent; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { color: #ccc; background-color: transparent; } .navbar-default .navbar-toggle { border-color: #ddd; } .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { background-color: #ddd; } .navbar-default .navbar-toggle .icon-bar { background-color: #888; } .navbar-default .navbar-collapse, .navbar-default .navbar-form { border-color: #e7e7e7; } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { color: #555; background-color: #e7e7e7; } @media (max-width: 767px) { .navbar-default .navbar-nav .open .dropdown-menu > li > a { color: #777; } .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { color: #333; background-color: transparent; } .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { color: #555; background-color: #e7e7e7; } .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #ccc; background-color: transparent; } } .navbar-default .navbar-link { color: #777; } .navbar-default .navbar-link:hover { color: #333; } .navbar-default .btn-link { color: #777; } .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { color: #333; } .navbar-default .btn-link[disabled]:hover, fieldset[disabled] .navbar-default .btn-link:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:focus { color: #ccc; } .navbar-inverse { background-color: #222; border-color: #080808; } .navbar-inverse .navbar-brand { color: #9d9d9d; } .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-text { color: #9d9d9d; } .navbar-inverse .navbar-nav > li > a { color: #9d9d9d; } .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus { color: #444; background-color: transparent; } .navbar-inverse .navbar-toggle { border-color: #333; } .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { background-color: #333; } .navbar-inverse .navbar-toggle .icon-bar { background-color: #fff; } .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { border-color: #101010; } .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { color: #fff; background-color: #080808; } @media (max-width: 767px) { .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { border-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu .divider { background-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { color: #9d9d9d; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { color: #fff; background-color: #080808; } .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #444; background-color: transparent; } } .navbar-inverse .navbar-link { color: #9d9d9d; } .navbar-inverse .navbar-link:hover { color: #fff; } .navbar-inverse .btn-link { color: #9d9d9d; } .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus { color: #fff; } .navbar-inverse .btn-link[disabled]:hover, fieldset[disabled] .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link[disabled]:focus, fieldset[disabled] .navbar-inverse .btn-link:focus { color: #444; } .breadcrumb { padding: 8px 15px; margin-bottom: 20px; list-style: none; background-color: #f5f5f5; border-radius: 4px; } .breadcrumb > li { display: inline-block; } .breadcrumb > li + li:before { padding: 0 5px; color: #ccc; content: "/\00a0"; } .breadcrumb > .active { color: #777; } .pagination { display: inline-block; padding-left: 0; margin: 20px 0; border-radius: 4px; } .pagination > li { display: inline; } .pagination > li > a, .pagination > li > span { position: relative; float: left; padding: 6px 12px; margin-left: -1px; line-height: 1.42857143; color: #337ab7; text-decoration: none; background-color: #fff; border: 1px solid #ddd; } .pagination > li:first-child > a, .pagination > li:first-child > span { margin-left: 0; border-top-left-radius: 4px; border-bottom-left-radius: 4px; } .pagination > li:last-child > a, .pagination > li:last-child > span { border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .pagination > li > a:hover, .pagination > li > span:hover, .pagination > li > a:focus, .pagination > li > span:focus { color: #23527c; background-color: #eee; border-color: #ddd; } .pagination > .active > a, .pagination > .active > span, .pagination > .active > a:hover, .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { z-index: 2; color: #fff; cursor: default; background-color: #337ab7; border-color: #337ab7; } .pagination > .disabled > span, .pagination > .disabled > span:hover, .pagination > .disabled > span:focus, .pagination > .disabled > a, .pagination > .disabled > a:hover, .pagination > .disabled > a:focus { color: #777; cursor: not-allowed; background-color: #fff; border-color: #ddd; } .pagination-lg > li > a, .pagination-lg > li > span { padding: 10px 16px; font-size: 18px; } .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span { border-top-left-radius: 6px; border-bottom-left-radius: 6px; } .pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span { border-top-right-radius: 6px; border-bottom-right-radius: 6px; } .pagination-sm > li > a, .pagination-sm > li > span { padding: 5px 10px; font-size: 12px; } .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span { border-top-left-radius: 3px; border-bottom-left-radius: 3px; } .pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } .pager { padding-left: 0; margin: 20px 0; text-align: center; list-style: none; } .pager li { display: inline; } .pager li > a, .pager li > span { display: inline-block; padding: 5px 14px; background-color: #fff; border: 1px solid #ddd; border-radius: 15px; } .pager li > a:hover, .pager li > a:focus { text-decoration: none; background-color: #eee; } .pager .next > a, .pager .next > span { float: right; } .pager .previous > a, .pager .previous > span { float: left; } .pager .disabled > a, .pager .disabled > a:hover, .pager .disabled > a:focus, .pager .disabled > span { color: #777; cursor: not-allowed; background-color: #fff; } .label { display: inline; padding: .2em .6em .3em; font-size: 75%; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25em; } a.label:hover, a.label:focus { color: #fff; text-decoration: none; cursor: pointer; } .label:empty { display: none; } .btn .label { position: relative; top: -1px; } .label-default { background-color: #777; } .label-default[href]:hover, .label-default[href]:focus { background-color: #5e5e5e; } .label-primary { background-color: #337ab7; } .label-primary[href]:hover, .label-primary[href]:focus { background-color: #286090; } .label-success { background-color: #5cb85c; } .label-success[href]:hover, .label-success[href]:focus { background-color: #449d44; } .label-info { background-color: #5bc0de; } .label-info[href]:hover, .label-info[href]:focus { background-color: #31b0d5; } .label-warning { background-color: #f0ad4e; } .label-warning[href]:hover, .label-warning[href]:focus { background-color: #ec971f; } .label-danger { background-color: #d9534f; } .label-danger[href]:hover, .label-danger[href]:focus { background-color: #c9302c; } .badge { display: inline-block; min-width: 10px; padding: 3px 7px; font-size: 12px; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; background-color: #777; border-radius: 10px; } .badge:empty { display: none; } .btn .badge { position: relative; top: -1px; } .btn-xs .badge { top: 0; padding: 1px 5px; } a.badge:hover, a.badge:focus { color: #fff; text-decoration: none; cursor: pointer; } .list-group-item.active > .badge, .nav-pills > .active > a > .badge { color: #337ab7; background-color: #fff; } .list-group-item > .badge { float: right; } .list-group-item > .badge + .badge { margin-right: 5px; } .nav-pills > li > a > .badge { margin-left: 3px; } .jumbotron { padding: 30px 15px; margin-bottom: 30px; color: inherit; background-color: #eee; } .jumbotron h1, .jumbotron .h1 { color: inherit; } .jumbotron p { margin-bottom: 15px; font-size: 21px; font-weight: 200; } .jumbotron > hr { border-top-color: #d5d5d5; } .container .jumbotron, .container-fluid .jumbotron { border-radius: 6px; } .jumbotron .container { max-width: 100%; } @media screen and (min-width: 768px) { .jumbotron { padding: 48px 0; } .container .jumbotron, .container-fluid .jumbotron { padding-right: 60px; padding-left: 60px; } .jumbotron h1, .jumbotron .h1 { font-size: 63px; } } .thumbnail { display: block; padding: 4px; margin-bottom: 20px; line-height: 1.42857143; background-color: #fff; border: 1px solid #ddd; border-radius: 4px; -webkit-transition: border .2s ease-in-out; -o-transition: border .2s ease-in-out; transition: border .2s ease-in-out; } .thumbnail > img, .thumbnail a > img { margin-right: auto; margin-left: auto; } a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active { border-color: #337ab7; } .thumbnail .caption { padding: 9px; color: #333; } .alert { padding: 15px; margin-bottom: 20px; border: 1px solid transparent; border-radius: 4px; } .alert h4 { margin-top: 0; color: inherit; } .alert .alert-link { font-weight: bold; } .alert > p, .alert > ul { margin-bottom: 0; } .alert > p + p { margin-top: 5px; } .alert-dismissable, .alert-dismissible { padding-right: 35px; } .alert-dismissable .close, .alert-dismissible .close { position: relative; top: -2px; right: -21px; color: inherit; } .alert-success { color: #3c763d; background-color: #dff0d8; border-color: #d6e9c6; } .alert-success hr { border-top-color: #c9e2b3; } .alert-success .alert-link { color: #2b542c; } .alert-info { color: #31708f; background-color: #d9edf7; border-color: #bce8f1; } .alert-info hr { border-top-color: #a6e1ec; } .alert-info .alert-link { color: #245269; } .alert-warning { color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; } .alert-warning hr { border-top-color: #f7e1b5; } .alert-warning .alert-link { color: #66512c; } .alert-danger { color: #a94442; background-color: #f2dede; border-color: #ebccd1; } .alert-danger hr { border-top-color: #e4b9c0; } .alert-danger .alert-link { color: #843534; } @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @-o-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } .progress { height: 20px; margin-bottom: 20px; overflow: hidden; background-color: #f5f5f5; border-radius: 4px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); } .progress-bar { float: left; width: 0; height: 100%; font-size: 12px; line-height: 20px; color: #fff; text-align: center; background-color: #337ab7; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); -webkit-transition: width .6s ease; -o-transition: width .6s ease; transition: width .6s ease; } .progress-striped .progress-bar, .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); -webkit-background-size: 40px 40px; background-size: 40px 40px; } .progress.active .progress-bar, .progress-bar.active { -webkit-animation: progress-bar-stripes 2s linear infinite; -o-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite; } .progress-bar-success { background-color: #5cb85c; } .progress-striped .progress-bar-success { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-info { background-color: #5bc0de; } .progress-striped .progress-bar-info { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-warning { background-color: #f0ad4e; } .progress-striped .progress-bar-warning { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .progress-bar-danger { background-color: #d9534f; } .progress-striped .progress-bar-danger { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); } .media { margin-top: 15px; } .media:first-child { margin-top: 0; } .media, .media-body { overflow: hidden; zoom: 1; } .media-body { width: 10000px; } .media-object { display: block; } .media-right, .media > .pull-right { padding-left: 10px; } .media-left, .media > .pull-left { padding-right: 10px; } .media-left, .media-right, .media-body { display: table-cell; vertical-align: top; } .media-middle { vertical-align: middle; } .media-bottom { vertical-align: bottom; } .media-heading { margin-top: 0; margin-bottom: 5px; } .media-list { padding-left: 0; list-style: none; } .list-group { padding-left: 0; margin-bottom: 20px; } .list-group-item { position: relative; display: block; padding: 10px 15px; margin-bottom: -1px; background-color: #fff; border: 1px solid #ddd; } .list-group-item:first-child { border-top-left-radius: 4px; border-top-right-radius: 4px; } .list-group-item:last-child { margin-bottom: 0; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; } a.list-group-item { color: #555; } a.list-group-item .list-group-item-heading { color: #333; } a.list-group-item:hover, a.list-group-item:focus { color: #555; text-decoration: none; background-color: #f5f5f5; } .list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus { color: #777; cursor: not-allowed; background-color: #eee; } .list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading { color: inherit; } .list-group-item.disabled .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text { color: #777; } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { z-index: 2; color: #fff; background-color: #337ab7; border-color: #337ab7; } .list-group-item.active .list-group-item-heading, .list-group-item.active:hover .list-group-item-heading, .list-group-item.active:focus .list-group-item-heading, .list-group-item.active .list-group-item-heading > small, .list-group-item.active:hover .list-group-item-heading > small, .list-group-item.active:focus .list-group-item-heading > small, .list-group-item.active .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading > .small { color: inherit; } .list-group-item.active .list-group-item-text, .list-group-item.active:hover .list-group-item-text, .list-group-item.active:focus .list-group-item-text { color: #c7ddef; } .list-group-item-success { color: #3c763d; background-color: #dff0d8; } a.list-group-item-success { color: #3c763d; } a.list-group-item-success .list-group-item-heading { color: inherit; } a.list-group-item-success:hover, a.list-group-item-success:focus { color: #3c763d; background-color: #d0e9c6; } a.list-group-item-success.active, a.list-group-item-success.active:hover, a.list-group-item-success.active:focus { color: #fff; background-color: #3c763d; border-color: #3c763d; } .list-group-item-info { color: #31708f; background-color: #d9edf7; } a.list-group-item-info { color: #31708f; } a.list-group-item-info .list-group-item-heading { color: inherit; } a.list-group-item-info:hover, a.list-group-item-info:focus { color: #31708f; background-color: #c4e3f3; } a.list-group-item-info.active, a.list-group-item-info.active:hover, a.list-group-item-info.active:focus { color: #fff; background-color: #31708f; border-color: #31708f; } .list-group-item-warning { color: #8a6d3b; background-color: #fcf8e3; } a.list-group-item-warning { color: #8a6d3b; } a.list-group-item-warning .list-group-item-heading { color: inherit; } a.list-group-item-warning:hover, a.list-group-item-warning:focus { color: #8a6d3b; background-color: #faf2cc; } a.list-group-item-warning.active, a.list-group-item-warning.active:hover, a.list-group-item-warning.active:focus { color: #fff; background-color: #8a6d3b; border-color: #8a6d3b; } .list-group-item-danger { color: #a94442; background-color: #f2dede; } a.list-group-item-danger { color: #a94442; } a.list-group-item-danger .list-group-item-heading { color: inherit; } a.list-group-item-danger:hover, a.list-group-item-danger:focus { color: #a94442; background-color: #ebcccc; } a.list-group-item-danger.active, a.list-group-item-danger.active:hover, a.list-group-item-danger.active:focus { color: #fff; background-color: #a94442; border-color: #a94442; } .list-group-item-heading { margin-top: 0; margin-bottom: 5px; } .list-group-item-text { margin-bottom: 0; line-height: 1.3; } .panel { margin-bottom: 20px; background-color: #fff; border: 1px solid transparent; border-radius: 4px; -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); box-shadow: 0 1px 1px rgba(0, 0, 0, .05); } .panel-body { padding: 15px; } .panel-heading { padding: 10px 15px; border-bottom: 1px solid transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel-heading > .dropdown .dropdown-toggle { color: inherit; } .panel-title { margin-top: 0; margin-bottom: 0; font-size: 16px; color: inherit; } .panel-title > a, .panel-title > small, .panel-title > .small, .panel-title > small > a, .panel-title > .small > a { color: inherit; } .panel-footer { padding: 10px 15px; background-color: #f5f5f5; border-top: 1px solid #ddd; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .list-group, .panel > .panel-collapse > .list-group { margin-bottom: 0; } .panel > .list-group .list-group-item, .panel > .panel-collapse > .list-group .list-group-item { border-width: 1px 0; border-radius: 0; } .panel > .list-group:first-child .list-group-item:first-child, .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { border-top: 0; border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .list-group:last-child .list-group-item:last-child, .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { border-bottom: 0; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel-heading + .list-group .list-group-item:first-child { border-top-width: 0; } .list-group + .panel-footer { border-top-width: 0; } .panel > .table, .panel > .table-responsive > .table, .panel > .panel-collapse > .table { margin-bottom: 0; } .panel > .table caption, .panel > .table-responsive > .table caption, .panel > .panel-collapse > .table caption { padding-right: 15px; padding-left: 15px; } .panel > .table:first-child, .panel > .table-responsive:first-child > .table:first-child { border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { border-top-left-radius: 3px; border-top-right-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { border-top-left-radius: 3px; } .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { border-top-right-radius: 3px; } .panel > .table:last-child, .panel > .table-responsive:last-child > .table:last-child { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { border-bottom-left-radius: 3px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { border-bottom-right-radius: 3px; } .panel > .panel-body + .table, .panel > .panel-body + .table-responsive, .panel > .table + .panel-body, .panel > .table-responsive + .panel-body { border-top: 1px solid #ddd; } .panel > .table > tbody:first-child > tr:first-child th, .panel > .table > tbody:first-child > tr:first-child td { border-top: 0; } .panel > .table-bordered, .panel > .table-responsive > .table-bordered { border: 0; } .panel > .table-bordered > thead > tr > th:first-child, .panel > .table-responsive > .table-bordered > thead > tr > th:first-child, .panel > .table-bordered > tbody > tr > th:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, .panel > .table-bordered > tfoot > tr > th:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, .panel > .table-bordered > thead > tr > td:first-child, .panel > .table-responsive > .table-bordered > thead > tr > td:first-child, .panel > .table-bordered > tbody > tr > td:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, .panel > .table-bordered > tfoot > tr > td:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .panel > .table-bordered > thead > tr > th:last-child, .panel > .table-responsive > .table-bordered > thead > tr > th:last-child, .panel > .table-bordered > tbody > tr > th:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, .panel > .table-bordered > tfoot > tr > th:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, .panel > .table-bordered > thead > tr > td:last-child, .panel > .table-responsive > .table-bordered > thead > tr > td:last-child, .panel > .table-bordered > tbody > tr > td:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, .panel > .table-bordered > tfoot > tr > td:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .panel > .table-bordered > thead > tr:first-child > td, .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, .panel > .table-bordered > tbody > tr:first-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, .panel > .table-bordered > thead > tr:first-child > th, .panel > .table-responsive > .table-bordered > thead > tr:first-child > th, .panel > .table-bordered > tbody > tr:first-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { border-bottom: 0; } .panel > .table-bordered > tbody > tr:last-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, .panel > .table-bordered > tfoot > tr:last-child > td, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, .panel > .table-bordered > tbody > tr:last-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, .panel > .table-bordered > tfoot > tr:last-child > th, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { border-bottom: 0; } .panel > .table-responsive { margin-bottom: 0; border: 0; } .panel-group { margin-bottom: 20px; } .panel-group .panel { margin-bottom: 0; border-radius: 4px; } .panel-group .panel + .panel { margin-top: 5px; } .panel-group .panel-heading { border-bottom: 0; } .panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group { border-top: 1px solid #ddd; } .panel-group .panel-footer { border-top: 0; } .panel-group .panel-footer + .panel-collapse .panel-body { border-bottom: 1px solid #ddd; } .panel-default { border-color: #ddd; } .panel-default > .panel-heading { color: #333; background-color: #f5f5f5; border-color: #ddd; } .panel-default > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ddd; } .panel-default > .panel-heading .badge { color: #f5f5f5; background-color: #333; } .panel-default > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ddd; } .panel-primary { border-color: #337ab7; } .panel-primary > .panel-heading { color: #fff; background-color: #337ab7; border-color: #337ab7; } .panel-primary > .panel-heading + .panel-collapse > .panel-body { border-top-color: #337ab7; } .panel-primary > .panel-heading .badge { color: #337ab7; background-color: #fff; } .panel-primary > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #337ab7; } .panel-success { border-color: #d6e9c6; } .panel-success > .panel-heading { color: #3c763d; background-color: #dff0d8; border-color: #d6e9c6; } .panel-success > .panel-heading + .panel-collapse > .panel-body { border-top-color: #d6e9c6; } .panel-success > .panel-heading .badge { color: #dff0d8; background-color: #3c763d; } .panel-success > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #d6e9c6; } .panel-info { border-color: #bce8f1; } .panel-info > .panel-heading { color: #31708f; background-color: #d9edf7; border-color: #bce8f1; } .panel-info > .panel-heading + .panel-collapse > .panel-body { border-top-color: #bce8f1; } .panel-info > .panel-heading .badge { color: #d9edf7; background-color: #31708f; } .panel-info > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #bce8f1; } .panel-warning { border-color: #faebcc; } .panel-warning > .panel-heading { color: #8a6d3b; background-color: #fcf8e3; border-color: #faebcc; } .panel-warning > .panel-heading + .panel-collapse > .panel-body { border-top-color: #faebcc; } .panel-warning > .panel-heading .badge { color: #fcf8e3; background-color: #8a6d3b; } .panel-warning > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #faebcc; } .panel-danger { border-color: #ebccd1; } .panel-danger > .panel-heading { color: #a94442; background-color: #f2dede; border-color: #ebccd1; } .panel-danger > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ebccd1; } .panel-danger > .panel-heading .badge { color: #f2dede; background-color: #a94442; } .panel-danger > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ebccd1; } .embed-responsive { position: relative; display: block; height: 0; padding: 0; overflow: hidden; } .embed-responsive .embed-responsive-item, .embed-responsive iframe, .embed-responsive embed, .embed-responsive object, .embed-responsive video { position: absolute; top: 0; bottom: 0; left: 0; width: 100%; height: 100%; border: 0; } .embed-responsive.embed-responsive-16by9 { padding-bottom: 56.25%; } .embed-responsive.embed-responsive-4by3 { padding-bottom: 75%; } .well { min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid #e3e3e3; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); } .well blockquote { border-color: #ddd; border-color: rgba(0, 0, 0, .15); } .well-lg { padding: 24px; border-radius: 6px; } .well-sm { padding: 9px; border-radius: 3px; } .close { float: right; font-size: 21px; font-weight: bold; line-height: 1; color: #000; text-shadow: 0 1px 0 #fff; filter: alpha(opacity=20); opacity: .2; } .close:hover, .close:focus { color: #000; text-decoration: none; cursor: pointer; filter: alpha(opacity=50); opacity: .5; } button.close { -webkit-appearance: none; padding: 0; cursor: pointer; background: transparent; border: 0; } .modal-open { overflow: hidden; } .modal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; display: none; overflow: hidden; -webkit-overflow-scrolling: touch; outline: 0; } .modal.fade .modal-dialog { -webkit-transition: -webkit-transform .3s ease-out; -o-transition: -o-transform .3s ease-out; transition: transform .3s ease-out; -webkit-transform: translate(0, -25%); -ms-transform: translate(0, -25%); -o-transform: translate(0, -25%); transform: translate(0, -25%); } .modal.in .modal-dialog { -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); } .modal-open .modal { overflow-x: hidden; overflow-y: auto; } .modal-dialog { position: relative; width: auto; margin: 10px; } .modal-content { position: relative; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #999; border: 1px solid rgba(0, 0, 0, .2); border-radius: 6px; outline: 0; -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); box-shadow: 0 3px 9px rgba(0, 0, 0, .5); } .modal-backdrop { position: absolute; top: 0; right: 0; left: 0; background-color: #000; } .modal-backdrop.fade { filter: alpha(opacity=0); opacity: 0; } .modal-backdrop.in { filter: alpha(opacity=50); opacity: .5; } .modal-header { min-height: 16.42857143px; padding: 15px; border-bottom: 1px solid #e5e5e5; } .modal-header .close { margin-top: -2px; } .modal-title { margin: 0; line-height: 1.42857143; } .modal-body { position: relative; padding: 15px; } .modal-footer { padding: 15px; text-align: right; border-top: 1px solid #e5e5e5; } .modal-footer .btn + .btn { margin-bottom: 0; margin-left: 5px; } .modal-footer .btn-group .btn + .btn { margin-left: -1px; } .modal-footer .btn-block + .btn-block { margin-left: 0; } .modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; } @media (min-width: 768px) { .modal-dialog { width: 600px; margin: 30px auto; } .modal-content { -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); box-shadow: 0 5px 15px rgba(0, 0, 0, .5); } .modal-sm { width: 300px; } } @media (min-width: 992px) { .modal-lg { width: 900px; } } .tooltip { position: absolute; z-index: 1070; display: block; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 12px; font-weight: normal; line-height: 1.4; visibility: visible; filter: alpha(opacity=0); opacity: 0; } .tooltip.in { filter: alpha(opacity=90); opacity: .9; } .tooltip.top { padding: 5px 0; margin-top: -3px; } .tooltip.right { padding: 0 5px; margin-left: 3px; } .tooltip.bottom { padding: 5px 0; margin-top: 3px; } .tooltip.left { padding: 0 5px; margin-left: -3px; } .tooltip-inner { max-width: 200px; padding: 3px 8px; color: #fff; text-align: center; text-decoration: none; background-color: #000; border-radius: 4px; } .tooltip-arrow { position: absolute; width: 0; height: 0; border-color: transparent; border-style: solid; } .tooltip.top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.top-left .tooltip-arrow { right: 5px; bottom: 0; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.top-right .tooltip-arrow { bottom: 0; left: 5px; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #000; } .tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; border-right-color: #000; } .tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; border-left-color: #000; } .tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .tooltip.bottom-left .tooltip-arrow { top: 0; right: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .tooltip.bottom-right .tooltip-arrow { top: 0; left: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #000; } .popover { position: absolute; top: 0; left: 0; z-index: 1060; display: none; max-width: 276px; padding: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 1.42857143; text-align: left; white-space: normal; background-color: #fff; -webkit-background-clip: padding-box; background-clip: padding-box; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, .2); border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); box-shadow: 0 5px 10px rgba(0, 0, 0, .2); } .popover.top { margin-top: -10px; } .popover.right { margin-left: 10px; } .popover.bottom { margin-top: 10px; } .popover.left { margin-left: -10px; } .popover-title { padding: 8px 14px; margin: 0; font-size: 14px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; border-radius: 5px 5px 0 0; } .popover-content { padding: 9px 14px; } .popover > .arrow, .popover > .arrow:after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid; } .popover > .arrow { border-width: 11px; } .popover > .arrow:after { content: ""; border-width: 10px; } .popover.top > .arrow { bottom: -11px; left: 50%; margin-left: -11px; border-top-color: #999; border-top-color: rgba(0, 0, 0, .25); border-bottom-width: 0; } .popover.top > .arrow:after { bottom: 1px; margin-left: -10px; content: " "; border-top-color: #fff; border-bottom-width: 0; } .popover.right > .arrow { top: 50%; left: -11px; margin-top: -11px; border-right-color: #999; border-right-color: rgba(0, 0, 0, .25); border-left-width: 0; } .popover.right > .arrow:after { bottom: -10px; left: 1px; content: " "; border-right-color: #fff; border-left-width: 0; } .popover.bottom > .arrow { top: -11px; left: 50%; margin-left: -11px; border-top-width: 0; border-bottom-color: #999; border-bottom-color: rgba(0, 0, 0, .25); } .popover.bottom > .arrow:after { top: 1px; margin-left: -10px; content: " "; border-top-width: 0; border-bottom-color: #fff; } .popover.left > .arrow { top: 50%; right: -11px; margin-top: -11px; border-right-width: 0; border-left-color: #999; border-left-color: rgba(0, 0, 0, .25); } .popover.left > .arrow:after { right: 1px; bottom: -10px; content: " "; border-right-width: 0; border-left-color: #fff; } .carousel { position: relative; } .carousel-inner { position: relative; width: 100%; overflow: hidden; } .carousel-inner > .item { position: relative; display: none; -webkit-transition: .6s ease-in-out left; -o-transition: .6s ease-in-out left; transition: .6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { line-height: 1; } @media all and (transform-3d), (-webkit-transform-3d) { .carousel-inner > .item { -webkit-transition: -webkit-transform .6s ease-in-out; -o-transition: -o-transform .6s ease-in-out; transition: transform .6s ease-in-out; -webkit-backface-visibility: hidden; backface-visibility: hidden; -webkit-perspective: 1000; perspective: 1000; } .carousel-inner > .item.next, .carousel-inner > .item.active.right { left: 0; -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } .carousel-inner > .item.prev, .carousel-inner > .item.active.left { left: 0; -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); } .carousel-inner > .item.next.left, .carousel-inner > .item.prev.right, .carousel-inner > .item.active { left: 0; -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { display: block; } .carousel-inner > .active { left: 0; } .carousel-inner > .next, .carousel-inner > .prev { position: absolute; top: 0; width: 100%; } .carousel-inner > .next { left: 100%; } .carousel-inner > .prev { left: -100%; } .carousel-inner > .next.left, .carousel-inner > .prev.right { left: 0; } .carousel-inner > .active.left { left: -100%; } .carousel-inner > .active.right { left: 100%; } .carousel-control { position: absolute; top: 0; bottom: 0; left: 0; width: 15%; font-size: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, .6); filter: alpha(opacity=50); opacity: .5; } .carousel-control.left { background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); background-repeat: repeat-x; } .carousel-control.right { right: 0; left: auto; background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); background-repeat: repeat-x; } .carousel-control:hover, .carousel-control:focus { color: #fff; text-decoration: none; filter: alpha(opacity=90); outline: 0; opacity: .9; } .carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right { position: absolute; top: 50%; z-index: 5; display: inline-block; } .carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { left: 50%; margin-left: -10px; } .carousel-control .icon-next, .carousel-control .glyphicon-chevron-right { right: 50%; margin-right: -10px; } .carousel-control .icon-prev, .carousel-control .icon-next { width: 20px; height: 20px; margin-top: -10px; font-family: serif; line-height: 1; } .carousel-control .icon-prev:before { content: '\2039'; } .carousel-control .icon-next:before { content: '\203a'; } .carousel-indicators { position: absolute; bottom: 10px; left: 50%; z-index: 15; width: 60%; padding-left: 0; margin-left: -30%; text-align: center; list-style: none; } .carousel-indicators li { display: inline-block; width: 10px; height: 10px; margin: 1px; text-indent: -999px; cursor: pointer; background-color: #000 \9; background-color: rgba(0, 0, 0, 0); border: 1px solid #fff; border-radius: 10px; } .carousel-indicators .active { width: 12px; height: 12px; margin: 0; background-color: #fff; } .carousel-caption { position: absolute; right: 15%; bottom: 20px; left: 15%; z-index: 10; padding-top: 20px; padding-bottom: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, .6); } .carousel-caption .btn { text-shadow: none; } @media screen and (min-width: 768px) { .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-prev, .carousel-control .icon-next { width: 30px; height: 30px; margin-top: -15px; font-size: 30px; } .carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev { margin-left: -15px; } .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next { margin-right: -15px; } .carousel-caption { right: 20%; left: 20%; padding-bottom: 30px; } .carousel-indicators { bottom: 20px; } } .clearfix:before, .clearfix:after, .dl-horizontal dd:before, .dl-horizontal dd:after, .container:before, .container:after, .container-fluid:before, .container-fluid:after, .row:before, .row:after, .form-horizontal .form-group:before, .form-horizontal .form-group:after, .btn-toolbar:before, .btn-toolbar:after, .btn-group-vertical > .btn-group:before, .btn-group-vertical > .btn-group:after, .nav:before, .nav:after, .navbar:before, .navbar:after, .navbar-header:before, .navbar-header:after, .navbar-collapse:before, .navbar-collapse:after, .pager:before, .pager:after, .panel-body:before, .panel-body:after, .modal-footer:before, .modal-footer:after { display: table; content: " "; } .clearfix:after, .dl-horizontal dd:after, .container:after, .container-fluid:after, .row:after, .form-horizontal .form-group:after, .btn-toolbar:after, .btn-group-vertical > .btn-group:after, .nav:after, .navbar:after, .navbar-header:after, .navbar-collapse:after, .pager:after, .panel-body:after, .modal-footer:after { clear: both; } .center-block { display: block; margin-right: auto; margin-left: auto; } .pull-right { float: right !important; } .pull-left { float: left !important; } .hide { display: none !important; } .show { display: block !important; } .invisible { visibility: hidden; } .text-hide { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; } .hidden { display: none !important; visibility: hidden !important; } .affix { position: fixed; } @-ms-viewport { width: device-width; } .visible-xs, .visible-sm, .visible-md, .visible-lg { display: none !important; } .visible-xs-block, .visible-xs-inline, .visible-xs-inline-block, .visible-sm-block, .visible-sm-inline, .visible-sm-inline-block, .visible-md-block, .visible-md-inline, .visible-md-inline-block, .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block { display: none !important; } @media (max-width: 767px) { .visible-xs { display: block !important; } table.visible-xs { display: table; } tr.visible-xs { display: table-row !important; } th.visible-xs, td.visible-xs { display: table-cell !important; } } @media (max-width: 767px) { .visible-xs-block { display: block !important; } } @media (max-width: 767px) { .visible-xs-inline { display: inline !important; } } @media (max-width: 767px) { .visible-xs-inline-block { display: inline-block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm { display: block !important; } table.visible-sm { display: table; } tr.visible-sm { display: table-row !important; } th.visible-sm, td.visible-sm { display: table-cell !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-block { display: block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline { display: inline !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline-block { display: inline-block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md { display: block !important; } table.visible-md { display: table; } tr.visible-md { display: table-row !important; } th.visible-md, td.visible-md { display: table-cell !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-block { display: block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline { display: inline !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline-block { display: inline-block !important; } } @media (min-width: 1200px) { .visible-lg { display: block !important; } table.visible-lg { display: table; } tr.visible-lg { display: table-row !important; } th.visible-lg, td.visible-lg { display: table-cell !important; } } @media (min-width: 1200px) { .visible-lg-block { display: block !important; } } @media (min-width: 1200px) { .visible-lg-inline { display: inline !important; } } @media (min-width: 1200px) { .visible-lg-inline-block { display: inline-block !important; } } @media (max-width: 767px) { .hidden-xs { display: none !important; } } @media (min-width: 768px) and (max-width: 991px) { .hidden-sm { display: none !important; } } @media (min-width: 992px) and (max-width: 1199px) { .hidden-md { display: none !important; } } @media (min-width: 1200px) { .hidden-lg { display: none !important; } } .visible-print { display: none !important; } @media print { .visible-print { display: block !important; } table.visible-print { display: table; } tr.visible-print { display: table-row !important; } th.visible-print, td.visible-print { display: table-cell !important; } } .visible-print-block { display: none !important; } @media print { .visible-print-block { display: block !important; } } .visible-print-inline { display: none !important; } @media print { .visible-print-inline { display: inline !important; } } .visible-print-inline-block { display: none !important; } @media print { .visible-print-inline-block { display: inline-block !important; } } @media print { .hidden-print { display: none !important; } } /*# sourceMappingURL=bootstrap.css.map */ ================================================ FILE: miaosha-admin/miaosha-admin-web/src/main/webapp/js/bootstrap-3.3.2-dist/js/bootstrap.js ================================================ /*! * Bootstrap v3.3.2 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') } +function ($) { 'use strict'; var version = $.fn.jquery.split(' ')[0].split('.') if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') } }(jQuery); /* ======================================================================== * Bootstrap: transition.js v3.3.2 * http://getbootstrap.com/javascript/#transitions * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) // ============================================================ function transitionEnd() { var el = document.createElement('bootstrap') var transEndEventNames = { WebkitTransition : 'webkitTransitionEnd', MozTransition : 'transitionend', OTransition : 'oTransitionEnd otransitionend', transition : 'transitionend' } for (var name in transEndEventNames) { if (el.style[name] !== undefined) { return { end: transEndEventNames[name] } } } return false // explicit for ie8 ( ._.) } // http://blog.alexmaccaw.com/css-transitions $.fn.emulateTransitionEnd = function (duration) { var called = false var $el = this $(this).one('bsTransitionEnd', function () { called = true }) var callback = function () { if (!called) $($el).trigger($.support.transition.end) } setTimeout(callback, duration) return this } $(function () { $.support.transition = transitionEnd() if (!$.support.transition) return $.event.special.bsTransitionEnd = { bindType: $.support.transition.end, delegateType: $.support.transition.end, handle: function (e) { if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) } } }) }(jQuery); /* ======================================================================== * Bootstrap: alert.js v3.3.2 * http://getbootstrap.com/javascript/#alerts * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // ALERT CLASS DEFINITION // ====================== var dismiss = '[data-dismiss="alert"]' var Alert = function (el) { $(el).on('click', dismiss, this.close) } Alert.VERSION = '3.3.2' Alert.TRANSITION_DURATION = 150 Alert.prototype.close = function (e) { var $this = $(this) var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = $(selector) if (e) e.preventDefault() if (!$parent.length) { $parent = $this.closest('.alert') } $parent.trigger(e = $.Event('close.bs.alert')) if (e.isDefaultPrevented()) return $parent.removeClass('in') function removeElement() { // detach from parent, fire event then clean up data $parent.detach().trigger('closed.bs.alert').remove() } $.support.transition && $parent.hasClass('fade') ? $parent .one('bsTransitionEnd', removeElement) .emulateTransitionEnd(Alert.TRANSITION_DURATION) : removeElement() } // ALERT PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.alert') if (!data) $this.data('bs.alert', (data = new Alert(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.alert $.fn.alert = Plugin $.fn.alert.Constructor = Alert // ALERT NO CONFLICT // ================= $.fn.alert.noConflict = function () { $.fn.alert = old return this } // ALERT DATA-API // ============== $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) }(jQuery); /* ======================================================================== * Bootstrap: button.js v3.3.2 * http://getbootstrap.com/javascript/#buttons * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // BUTTON PUBLIC CLASS DEFINITION // ============================== var Button = function (element, options) { this.$element = $(element) this.options = $.extend({}, Button.DEFAULTS, options) this.isLoading = false } Button.VERSION = '3.3.2' Button.DEFAULTS = { loadingText: 'loading...' } Button.prototype.setState = function (state) { var d = 'disabled' var $el = this.$element var val = $el.is('input') ? 'val' : 'html' var data = $el.data() state = state + 'Text' if (data.resetText == null) $el.data('resetText', $el[val]()) // push to event loop to allow forms to submit setTimeout($.proxy(function () { $el[val](data[state] == null ? this.options[state] : data[state]) if (state == 'loadingText') { this.isLoading = true $el.addClass(d).attr(d, d) } else if (this.isLoading) { this.isLoading = false $el.removeClass(d).removeAttr(d) } }, this), 0) } Button.prototype.toggle = function () { var changed = true var $parent = this.$element.closest('[data-toggle="buttons"]') if ($parent.length) { var $input = this.$element.find('input') if ($input.prop('type') == 'radio') { if ($input.prop('checked') && this.$element.hasClass('active')) changed = false else $parent.find('.active').removeClass('active') } if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') } else { this.$element.attr('aria-pressed', !this.$element.hasClass('active')) } if (changed) this.$element.toggleClass('active') } // BUTTON PLUGIN DEFINITION // ======================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.button') var options = typeof option == 'object' && option if (!data) $this.data('bs.button', (data = new Button(this, options))) if (option == 'toggle') data.toggle() else if (option) data.setState(option) }) } var old = $.fn.button $.fn.button = Plugin $.fn.button.Constructor = Button // BUTTON NO CONFLICT // ================== $.fn.button.noConflict = function () { $.fn.button = old return this } // BUTTON DATA-API // =============== $(document) .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { var $btn = $(e.target) if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') Plugin.call($btn, 'toggle') e.preventDefault() }) .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) }) }(jQuery); /* ======================================================================== * Bootstrap: carousel.js v3.3.2 * http://getbootstrap.com/javascript/#carousel * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CAROUSEL CLASS DEFINITION // ========================= var Carousel = function (element, options) { this.$element = $(element) this.$indicators = this.$element.find('.carousel-indicators') this.options = options this.paused = this.sliding = this.interval = this.$active = this.$items = null this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) } Carousel.VERSION = '3.3.2' Carousel.TRANSITION_DURATION = 600 Carousel.DEFAULTS = { interval: 5000, pause: 'hover', wrap: true, keyboard: true } Carousel.prototype.keydown = function (e) { if (/input|textarea/i.test(e.target.tagName)) return switch (e.which) { case 37: this.prev(); break case 39: this.next(); break default: return } e.preventDefault() } Carousel.prototype.cycle = function (e) { e || (this.paused = false) this.interval && clearInterval(this.interval) this.options.interval && !this.paused && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) return this } Carousel.prototype.getItemIndex = function (item) { this.$items = item.parent().children('.item') return this.$items.index(item || this.$active) } Carousel.prototype.getItemForDirection = function (direction, active) { var activeIndex = this.getItemIndex(active) var willWrap = (direction == 'prev' && activeIndex === 0) || (direction == 'next' && activeIndex == (this.$items.length - 1)) if (willWrap && !this.options.wrap) return active var delta = direction == 'prev' ? -1 : 1 var itemIndex = (activeIndex + delta) % this.$items.length return this.$items.eq(itemIndex) } Carousel.prototype.to = function (pos) { var that = this var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) if (pos > (this.$items.length - 1) || pos < 0) return if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" if (activeIndex == pos) return this.pause().cycle() return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) } Carousel.prototype.pause = function (e) { e || (this.paused = true) if (this.$element.find('.next, .prev').length && $.support.transition) { this.$element.trigger($.support.transition.end) this.cycle(true) } this.interval = clearInterval(this.interval) return this } Carousel.prototype.next = function () { if (this.sliding) return return this.slide('next') } Carousel.prototype.prev = function () { if (this.sliding) return return this.slide('prev') } Carousel.prototype.slide = function (type, next) { var $active = this.$element.find('.item.active') var $next = next || this.getItemForDirection(type, $active) var isCycling = this.interval var direction = type == 'next' ? 'left' : 'right' var that = this if ($next.hasClass('active')) return (this.sliding = false) var relatedTarget = $next[0] var slideEvent = $.Event('slide.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) this.$element.trigger(slideEvent) if (slideEvent.isDefaultPrevented()) return this.sliding = true isCycling && this.pause() if (this.$indicators.length) { this.$indicators.find('.active').removeClass('active') var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) $nextIndicator && $nextIndicator.addClass('active') } var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" if ($.support.transition && this.$element.hasClass('slide')) { $next.addClass(type) $next[0].offsetWidth // force reflow $active.addClass(direction) $next.addClass(direction) $active .one('bsTransitionEnd', function () { $next.removeClass([type, direction].join(' ')).addClass('active') $active.removeClass(['active', direction].join(' ')) that.sliding = false setTimeout(function () { that.$element.trigger(slidEvent) }, 0) }) .emulateTransitionEnd(Carousel.TRANSITION_DURATION) } else { $active.removeClass('active') $next.addClass('active') this.sliding = false this.$element.trigger(slidEvent) } isCycling && this.cycle() return this } // CAROUSEL PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.carousel') var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) var action = typeof option == 'string' ? option : options.slide if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) if (typeof option == 'number') data.to(option) else if (action) data[action]() else if (options.interval) data.pause().cycle() }) } var old = $.fn.carousel $.fn.carousel = Plugin $.fn.carousel.Constructor = Carousel // CAROUSEL NO CONFLICT // ==================== $.fn.carousel.noConflict = function () { $.fn.carousel = old return this } // CAROUSEL DATA-API // ================= var clickHandler = function (e) { var href var $this = $(this) var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 if (!$target.hasClass('carousel')) return var options = $.extend({}, $target.data(), $this.data()) var slideIndex = $this.attr('data-slide-to') if (slideIndex) options.interval = false Plugin.call($target, options) if (slideIndex) { $target.data('bs.carousel').to(slideIndex) } e.preventDefault() } $(document) .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) $(window).on('load', function () { $('[data-ride="carousel"]').each(function () { var $carousel = $(this) Plugin.call($carousel, $carousel.data()) }) }) }(jQuery); /* ======================================================================== * Bootstrap: collapse.js v3.3.2 * http://getbootstrap.com/javascript/#collapse * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // COLLAPSE PUBLIC CLASS DEFINITION // ================================ var Collapse = function (element, options) { this.$element = $(element) this.options = $.extend({}, Collapse.DEFAULTS, options) this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') this.transitioning = null if (this.options.parent) { this.$parent = this.getParent() } else { this.addAriaAndCollapsedClass(this.$element, this.$trigger) } if (this.options.toggle) this.toggle() } Collapse.VERSION = '3.3.2' Collapse.TRANSITION_DURATION = 350 Collapse.DEFAULTS = { toggle: true, trigger: '[data-toggle="collapse"]' } Collapse.prototype.dimension = function () { var hasWidth = this.$element.hasClass('width') return hasWidth ? 'width' : 'height' } Collapse.prototype.show = function () { if (this.transitioning || this.$element.hasClass('in')) return var activesData var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') if (actives && actives.length) { activesData = actives.data('bs.collapse') if (activesData && activesData.transitioning) return } var startEvent = $.Event('show.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return if (actives && actives.length) { Plugin.call(actives, 'hide') activesData || actives.data('bs.collapse', null) } var dimension = this.dimension() this.$element .removeClass('collapse') .addClass('collapsing')[dimension](0) .attr('aria-expanded', true) this.$trigger .removeClass('collapsed') .attr('aria-expanded', true) this.transitioning = 1 var complete = function () { this.$element .removeClass('collapsing') .addClass('collapse in')[dimension]('') this.transitioning = 0 this.$element .trigger('shown.bs.collapse') } if (!$.support.transition) return complete.call(this) var scrollSize = $.camelCase(['scroll', dimension].join('-')) this.$element .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) } Collapse.prototype.hide = function () { if (this.transitioning || !this.$element.hasClass('in')) return var startEvent = $.Event('hide.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return var dimension = this.dimension() this.$element[dimension](this.$element[dimension]())[0].offsetHeight this.$element .addClass('collapsing') .removeClass('collapse in') .attr('aria-expanded', false) this.$trigger .addClass('collapsed') .attr('aria-expanded', false) this.transitioning = 1 var complete = function () { this.transitioning = 0 this.$element .removeClass('collapsing') .addClass('collapse') .trigger('hidden.bs.collapse') } if (!$.support.transition) return complete.call(this) this.$element [dimension](0) .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION) } Collapse.prototype.toggle = function () { this[this.$element.hasClass('in') ? 'hide' : 'show']() } Collapse.prototype.getParent = function () { return $(this.options.parent) .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') .each($.proxy(function (i, element) { var $element = $(element) this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) }, this)) .end() } Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { var isOpen = $element.hasClass('in') $element.attr('aria-expanded', isOpen) $trigger .toggleClass('collapsed', !isOpen) .attr('aria-expanded', isOpen) } function getTargetFromTrigger($trigger) { var href var target = $trigger.attr('data-target') || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 return $(target) } // COLLAPSE PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.collapse') var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data && options.toggle && option == 'show') options.toggle = false if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.collapse $.fn.collapse = Plugin $.fn.collapse.Constructor = Collapse // COLLAPSE NO CONFLICT // ==================== $.fn.collapse.noConflict = function () { $.fn.collapse = old return this } // COLLAPSE DATA-API // ================= $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { var $this = $(this) if (!$this.attr('data-target')) e.preventDefault() var $target = getTargetFromTrigger($this) var data = $target.data('bs.collapse') var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) Plugin.call($target, option) }) }(jQuery); /* ======================================================================== * Bootstrap: dropdown.js v3.3.2 * http://getbootstrap.com/javascript/#dropdowns * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // DROPDOWN CLASS DEFINITION // ========================= var backdrop = '.dropdown-backdrop' var toggle = '[data-toggle="dropdown"]' var Dropdown = function (element) { $(element).on('click.bs.dropdown', this.toggle) } Dropdown.VERSION = '3.3.2' Dropdown.prototype.toggle = function (e) { var $this = $(this) if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') clearMenus() if (!isActive) { if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { // if mobile we use a backdrop because click events don't delegate $('