├── README.md
├── auth-service
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── mycat
│ │ └── monoeshop
│ │ ├── App.java
│ │ ├── config
│ │ └── MyAppConfig.java
│ │ ├── mapper
│ │ └── AccountMapper.java
│ │ ├── model
│ │ └── Account.java
│ │ ├── rest
│ │ └── AccountRestService.java
│ │ └── service
│ │ └── AccountService.java
│ └── resources
│ ├── application.yml
│ ├── create-db.sql
│ ├── demo-data.sql
│ └── logback.xml
├── cart-service
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── mycat
│ │ └── monoeshop
│ │ ├── App.java
│ │ ├── config
│ │ └── MyAppConfig.java
│ │ ├── model
│ │ ├── Account.java
│ │ ├── CartRecord.java
│ │ ├── Product.java
│ │ ├── Result.java
│ │ └── ResultEnum.java
│ │ ├── rest
│ │ └── CartRestService.java
│ │ └── service
│ │ └── CartService.java
│ └── resources
│ ├── application.yml
│ └── logback.xml
├── config
└── zuul
│ └── application.yml
├── eshop-web
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── mycat
│ │ └── monoeshop
│ │ ├── App.java
│ │ ├── JacksonUtil.java
│ │ ├── config
│ │ ├── SecurityConfig.java
│ │ └── SecurityInterceptor.java
│ │ ├── controller
│ │ ├── AccountController.java
│ │ ├── CartController.java
│ │ ├── Mainpage.java
│ │ └── ProductController.java
│ │ ├── model
│ │ ├── Account.java
│ │ ├── CartRecord.java
│ │ ├── Product.java
│ │ ├── Result.java
│ │ └── ResultEnum.java
│ │ └── service
│ │ └── rest
│ │ ├── AccountService.java
│ │ ├── CartService.java
│ │ ├── ProductService.java
│ │ └── SessionService.java
│ └── resources
│ ├── application.yml
│ ├── logback.xml
│ └── static
│ ├── cart.html
│ ├── css
│ ├── bootstrap-table.min.css
│ ├── bootstrap-theme.min.css
│ ├── bootstrap-theme.min.css.map
│ ├── bootstrap.min.css
│ ├── bootstrap.min.css.map
│ ├── css
│ ├── font-awesome.min.css
│ ├── fontawesome-webfont.woff2
│ ├── form-elements.css
│ ├── product.css
│ ├── style-responsive.css
│ └── style.css
│ ├── detail.html
│ ├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ └── glyphicons-halflings-regular.woff2
│ ├── img
│ └── background.jpg
│ ├── js
│ ├── bootbox.min.js
│ ├── bootstrap-table-locale-all.min.js
│ ├── bootstrap-table.min.js
│ ├── bootstrap.min.js
│ ├── cart.js
│ ├── detail.js
│ ├── index.js
│ ├── jquery-3.2.1.min.js
│ ├── jquery.backstretch.min.js
│ ├── json2.js
│ ├── main.js
│ ├── npm.js
│ ├── product.js
│ └── urlparam.js
│ ├── login.html
│ ├── main.html
│ └── product.html
├── eureka-server
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── mycat
│ │ └── monoeshop
│ │ └── App.java
│ └── resources
│ ├── application.yml
│ └── logback.xml
├── pom.xml
├── product-service
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── mycat
│ │ └── monoeshop
│ │ ├── App.java
│ │ ├── config
│ │ └── MyAppConfig.java
│ │ ├── mapper
│ │ └── ProductMapper.java
│ │ ├── model
│ │ └── Product.java
│ │ ├── rest
│ │ └── ProductRestService.java
│ │ └── service
│ │ └── ProductService.java
│ └── resources
│ ├── application.yml
│ ├── create-db.sql
│ ├── demo-data.sql
│ └── logback.xml
└── zuul-gateway
├── pom.xml
└── src
└── main
├── java
└── com
│ └── mycat
│ └── monoeshop
│ ├── App.java
│ ├── config
│ ├── FilterConfig.java
│ └── MyAppConfig.java
│ ├── controller
│ └── SessionController.java
│ ├── filter
│ ├── JacksonUtil.java
│ ├── LoginPostFilter.java
│ └── SecurityPreFilter.java
│ └── model
│ ├── Account.java
│ ├── Result.java
│ └── ResultEnum.java
└── resources
├── application.yml
└── logback.xml
/README.md:
--------------------------------------------------------------------------------
1 | # SpringCloud_eShop
2 | Spring Cloud架构的eshop工程代码
3 |
--------------------------------------------------------------------------------
/auth-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | Springcloud_eShop
6 | Springcloud_eShop
7 | 0.0.1-SNAPSHOT
8 |
9 | sc_auth-service
10 | sc_auth-service
11 | jar
12 |
13 |
14 | org.mybatis.spring.boot
15 | mybatis-spring-boot-starter
16 | ${mybatis.version}
17 |
18 |
19 |
20 | com.alibaba
21 | druid
22 | ${druid.version}
23 |
24 |
25 | mysql
26 | mysql-connector-java
27 |
28 |
29 |
30 |
31 | eshop_sc_auth_service
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-maven-plugin
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/auth-service/src/main/java/com/mycat/monoeshop/App.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7 |
8 | /**
9 | * Desc:
10 | *
11 | * @date: 27/08/2017
12 | * @author: Leader us
13 | */
14 | @SpringBootApplication
15 | @EnableDiscoveryClient
16 | @MapperScan("com.mycat.monoeshop.mapper")
17 | public class App {
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(App.class, args);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/auth-service/src/main/java/com/mycat/monoeshop/config/MyAppConfig.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.config;
2 |
3 | import javax.sql.DataSource;
4 |
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.cache.annotation.CachingConfigurerSupport;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | import com.alibaba.druid.pool.DruidDataSource;
11 |
12 | /**
13 | * Desc:
14 | *
15 | * @date: 27/08/2017
16 | * @author: Leader us
17 | */
18 | @Configuration
19 | public class MyAppConfig extends CachingConfigurerSupport {
20 |
21 | @Configuration
22 | public class DruidDataSourceConfig {
23 | @Bean
24 | @ConfigurationProperties(prefix = "spring.datasource")
25 | public DataSource druidDataSource() {
26 | DruidDataSource druidDataSource = new DruidDataSource();
27 | return druidDataSource;
28 | }
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/auth-service/src/main/java/com/mycat/monoeshop/mapper/AccountMapper.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.mapper;
2 |
3 |
4 | import org.apache.ibatis.annotations.Param;
5 | import org.apache.ibatis.annotations.Select;
6 |
7 | import com.mycat.monoeshop.model.Account;
8 |
9 | /**
10 | * Desc:
11 | *
12 | * @date: 27/08/2017
13 | * @author: Leader us
14 | */
15 | public interface AccountMapper {
16 | @Select("select * from account where name=#{name,jdbcType=VARCHAR} and password=#{password,jdbcType=VARCHAR}")
17 | Account getAccountByNameAndPwd(@Param("name") String name, @Param("password") String password);
18 | }
19 |
--------------------------------------------------------------------------------
/auth-service/src/main/java/com/mycat/monoeshop/model/Account.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public class Account {
10 | private String name;
11 | private String password;
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | public void setName(String name) {
18 | this.name = name;
19 | }
20 |
21 | public String getPassword() {
22 | return password;
23 | }
24 |
25 | public void setPassword(String password) {
26 | this.password = password;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/auth-service/src/main/java/com/mycat/monoeshop/rest/AccountRestService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.rest;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 |
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.web.bind.annotation.RequestMapping;
7 | import org.springframework.web.bind.annotation.RequestMethod;
8 | import org.springframework.web.bind.annotation.RestController;
9 |
10 | import com.mycat.monoeshop.model.Account;
11 | import com.mycat.monoeshop.service.AccountService;
12 |
13 | /**
14 | * Desc:
15 | *
16 | * @date: 27/08/2017
17 | * @author: Leader us
18 | */
19 | @RestController
20 | @RequestMapping("/account")
21 | public class AccountRestService {
22 | @Autowired
23 | private AccountService accountService;
24 |
25 | @RequestMapping(value = "login", method = RequestMethod.POST)
26 | public Account login(HttpServletRequest request, String username, String password) {
27 | Account accont = accountService.login(username, password);
28 | return accont;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/auth-service/src/main/java/com/mycat/monoeshop/service/AccountService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.service;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 |
8 | import com.mycat.monoeshop.mapper.AccountMapper;
9 | import com.mycat.monoeshop.model.Account;
10 |
11 | /**
12 | * Desc:
13 | *
14 | * @date: 27/08/2017
15 | * @author: Leader us
16 | */
17 | @Service
18 | public class AccountService {
19 | private static final Logger LOGGER = LoggerFactory.getLogger(AccountService.class);
20 |
21 | @Autowired
22 | private AccountMapper accountMapper;
23 |
24 | public Account login(String username, String password) {
25 | LOGGER.info("account login, username: {}, password: {}", username, password);
26 | return accountMapper.getAccountByNameAndPwd(username, password);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/auth-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: eshop-auth-service
4 | datasource:
5 | type: com.alibaba.druid.pool.DruidDataSource
6 | url: jdbc:mysql://192.168.18.134:3306/HPE_APP?useSSL=false
7 | username: lession
8 | password: mypass
9 | driver-class-name: com.mysql.jdbc.Driver
10 | initialSize: 2
11 | minIdle: 2
12 | maxActive: 20
13 | maxWait: 60000
14 | timeBetweenEvictionRunsMillis: 60000
15 | minEvictableIdleTimeMillis: 300000
16 | validationQuery: SELECT 1 FROM DUAL
17 | testWhileIdle: true
18 | testOnBorrow: true
19 | testOnReturn: false
20 | poolPreparedStatements: true
21 | maxPoolPreparedStatementPerConnectionSize: 20
22 | schema: classpath:create-db.sql
23 | data: classpath:demo-data.sql
24 | initialize: true
25 | continueOnError: true
26 | info:
27 | app:
28 | name: ${spring.application.name}
29 | version: v1.0.0
30 | server:
31 | port: 8034
32 | context-path: /
33 | tomcat:
34 | uri-encoding: UTF-8
35 | logging:
36 | config: classpath:logback.xml
37 | eureka:
38 | instance:
39 | hostname: 127.0.0.1
40 | prefer-ip-address: true
41 | client:
42 | healthcheck:
43 | enabled: true
44 | registerWithEureka: true
45 | fetchRegistry: true
46 | service-url:
47 | defaultZone: http://127.0.0.1:8030/eureka/
48 |
49 |
--------------------------------------------------------------------------------
/auth-service/src/main/resources/create-db.sql:
--------------------------------------------------------------------------------
1 | --创建account表
2 | CREATE TABLE IF NOT EXISTS `account`(
3 | `name` VARCHAR(20),
4 | `password` VARCHAR(20) NOT NULL,
5 | PRIMARY KEY ( `name` )
6 | )ENGINE=InnoDB DEFAULT CHARSET=utf8;
7 |
--------------------------------------------------------------------------------
/auth-service/src/main/resources/demo-data.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO account VALUES ('guest','111111');
2 |
3 |
--------------------------------------------------------------------------------
/auth-service/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/cart-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | Springcloud_eShop
6 | Springcloud_eShop
7 | 0.0.1-SNAPSHOT
8 |
9 | sc_cart-service
10 | sc_cart-service
11 | jar
12 |
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-data-redis
17 |
18 |
19 | com.fasterxml.jackson.core
20 | jackson-core
21 |
22 |
23 | com.fasterxml.jackson.core
24 | jackson-annotations
25 |
26 |
27 | com.fasterxml.jackson.core
28 | jackson-databind
29 |
30 |
31 |
32 |
33 |
34 | eshop_sc_cart-service
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-maven-plugin
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/App.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 |
7 | /**
8 | * Desc:
9 | *
10 | * @date: 27/08/2017
11 | * @author: Leader us
12 | */
13 | @SpringBootApplication
14 | @EnableDiscoveryClient
15 | public class App {
16 |
17 | public static void main(String[] args) {
18 | SpringApplication.run(App.class, args);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/config/MyAppConfig.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.config;
2 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
3 | import com.fasterxml.jackson.annotation.PropertyAccessor;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 |
6 | import javax.sql.DataSource;
7 |
8 | import org.springframework.boot.context.properties.ConfigurationProperties;
9 | import org.springframework.cache.CacheManager;
10 | import org.springframework.cache.annotation.CachingConfigurerSupport;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 | import org.springframework.data.redis.cache.RedisCacheManager;
14 | import org.springframework.data.redis.connection.RedisConnectionFactory;
15 | import org.springframework.data.redis.core.RedisTemplate;
16 | import org.springframework.data.redis.core.StringRedisTemplate;
17 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
18 | import org.springframework.data.redis.serializer.RedisSerializer;
19 | import org.springframework.data.redis.serializer.StringRedisSerializer;
20 |
21 | /**
22 | * Desc:
23 | *
24 | * @date: 27/08/2017
25 | * @author: Leader us
26 | */
27 | @Configuration
28 | public class MyAppConfig extends CachingConfigurerSupport {
29 |
30 | @Bean
31 | public CacheManager cacheManager(RedisTemplate redisTemplate) {
32 | RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
33 | // 设置缓存过期时间
34 | // rcm.setDefaultExpiration(60);//秒
35 | return rcm;
36 |
37 | }
38 |
39 | /**
40 | * RedisTemplate配置
41 | */
42 | @Bean
43 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
44 | StringRedisTemplate template = new StringRedisTemplate(factory);
45 | // 定义key序列化方式
46 | RedisSerializer redisSerializer = new StringRedisSerializer();// Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
47 | // 定义value的序列化方式
48 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
49 | ObjectMapper om = new ObjectMapper();
50 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
51 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
52 | jackson2JsonRedisSerializer.setObjectMapper(om);
53 |
54 | template.setKeySerializer(jackson2JsonRedisSerializer);
55 | template.setValueSerializer(jackson2JsonRedisSerializer);
56 | template.setHashKeySerializer(jackson2JsonRedisSerializer);
57 | template.setHashValueSerializer(jackson2JsonRedisSerializer);
58 | template.afterPropertiesSet();
59 | return template;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/model/Account.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public class Account {
10 | private String name;
11 | private String password;
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | public void setName(String name) {
18 | this.name = name;
19 | }
20 |
21 | public String getPassword() {
22 | return password;
23 | }
24 |
25 | public void setPassword(String password) {
26 | this.password = password;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/model/CartRecord.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | import java.math.BigDecimal;
4 | import java.util.Date;
5 |
6 | /**
7 | * Desc:
8 | *
9 | * @date: 27/08/2017
10 | * @author: Leader us
11 | */
12 | public class CartRecord {
13 | private Integer productId;
14 | private String productName;
15 | private BigDecimal productPrice;
16 | private String username;
17 | private Date time;
18 | private Integer count;
19 |
20 | public Integer getProductId() {
21 | return productId;
22 | }
23 |
24 | public void setProductId(Integer productId) {
25 | this.productId = productId;
26 | }
27 |
28 | public String getProductName() {
29 | return productName;
30 | }
31 |
32 | public void setProductName(String productName) {
33 | this.productName = productName;
34 | }
35 |
36 | public BigDecimal getProductPrice() {
37 | return productPrice;
38 | }
39 |
40 | public void setProductPrice(BigDecimal productPrice) {
41 | this.productPrice = productPrice;
42 | }
43 |
44 | public String getUsername() {
45 | return username;
46 | }
47 |
48 | public void setUsername(String username) {
49 | this.username = username;
50 | }
51 |
52 | public Date getTime() {
53 | return time;
54 | }
55 |
56 | public void setTime(Date time) {
57 | this.time = time;
58 | }
59 |
60 | public Integer getCount() {
61 | return count;
62 | }
63 |
64 | public void setCount(Integer count) {
65 | this.count = count;
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return "CartRecord{" +
71 | "productId='" + productId + '\'' +
72 | ", productName='" + productName + '\'' +
73 | ", productPrice=" + productPrice +
74 | ", username='" + username + '\'' +
75 | ", time=" + time +
76 | ", count=" + count +
77 | '}';
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/model/Product.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | import java.math.BigDecimal;
4 |
5 | /**
6 | * Desc:
7 | *
8 | * @date: 27/08/2017
9 | * @author: Leader us
10 | */
11 | public class Product {
12 | private Integer id;
13 | private String name;
14 | private BigDecimal price;
15 | private String desc;
16 |
17 | public Integer getId() {
18 | return id;
19 | }
20 |
21 | public void setId(Integer id) {
22 | this.id = id;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 |
33 | public BigDecimal getPrice() {
34 | return price;
35 | }
36 |
37 | public void setPrice(BigDecimal price) {
38 | this.price = price;
39 | }
40 |
41 | public String getDesc() {
42 | return desc;
43 | }
44 |
45 | public void setDesc(String desc) {
46 | this.desc = desc;
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "Product{" +
52 | "id=" + id +
53 | ", name='" + name + '\'' +
54 | ", price=" + price +
55 | ", desc='" + desc + '\'' +
56 | '}';
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/model/Result.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public class Result {
10 | private int code;
11 | private String desc;
12 | private T data;
13 |
14 | public Result()
15 | {
16 |
17 | }
18 | public Result(ResultEnum resultEnum) {
19 | this.code = resultEnum.getCode();
20 | this.desc = resultEnum.getDesc();
21 | }
22 |
23 | public Result(ResultEnum resultEnum, T data) {
24 | this.code = resultEnum.getCode();
25 | this.desc = resultEnum.getDesc();
26 | this.data = data;
27 | }
28 |
29 | public int getCode() {
30 | return code;
31 | }
32 |
33 | public void setCode(int code) {
34 | this.code = code;
35 | }
36 |
37 | public String getDesc() {
38 | return desc;
39 | }
40 |
41 | public void setDesc(String desc) {
42 | this.desc = desc;
43 | }
44 |
45 | public T getData() {
46 | return data;
47 | }
48 |
49 | public void setData(T data) {
50 | this.data = data;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/model/ResultEnum.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public enum ResultEnum {
10 | SUCCESS(200, "success"), ERROR(502, "error"), NOT_LOGIN(503, "not login");
11 |
12 | private int code;
13 | private String desc;
14 |
15 | ResultEnum(int code, String desc) {
16 | this.code = code;
17 | this.desc = desc;
18 | }
19 |
20 | public int getCode() {
21 | return code;
22 | }
23 |
24 | public String getDesc() {
25 | return desc;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/rest/CartRestService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.rest;
2 |
3 | import java.util.List;
4 | import java.util.stream.Stream;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.web.bind.annotation.RequestBody;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import com.mycat.monoeshop.model.CartRecord;
16 | import com.mycat.monoeshop.model.Result;
17 | import com.mycat.monoeshop.service.CartService;
18 |
19 | /**
20 | * Desc:
21 | *
22 | * @date: 27/08/2017
23 | * @author: Leader us
24 | */
25 | @RestController()
26 | @RequestMapping("/cart")
27 | public class CartRestService {
28 | private static final Logger LOGGER = LoggerFactory.getLogger(CartRestService.class);
29 | @Autowired
30 | private CartService cartService;
31 |
32 | @RequestMapping("records")
33 | public List getProductsByUsername(HttpServletRequest request) {
34 | LOGGER.info("get cart for user " + request.getSession().getId());
35 | Stream.of(request.getCookies()).forEach(a -> {
36 | System.out.println("yyy cookie " + a.getName() + " " + a.getValue());
37 | });
38 | String userName = request.getHeader("accountName");
39 | LOGGER.info("get cart for user " + userName);
40 | return cartService.getProductsByUsername(userName);
41 | }
42 |
43 | @RequestMapping("add-cart")
44 | public Result addProductToCart(@RequestBody CartRecord cartRecord, HttpServletRequest request) {
45 | cartRecord.setUsername(request.getHeader("accountName"));
46 | LOGGER.info("add goods to cart " + cartRecord);
47 | return cartService.addProductToCart(cartRecord);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/cart-service/src/main/java/com/mycat/monoeshop/service/CartService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.service;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 |
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.data.redis.core.ListOperations;
10 | import org.springframework.data.redis.core.RedisTemplate;
11 | import org.springframework.stereotype.Service;
12 |
13 | import com.mycat.monoeshop.model.CartRecord;
14 | import com.mycat.monoeshop.model.Result;
15 | import com.mycat.monoeshop.model.ResultEnum;
16 |
17 | /**
18 | * Desc:
19 | *
20 | * @date: 27/08/2017
21 | * @author: Leader us
22 | */
23 | @Service
24 | public class CartService {
25 | private static final Logger LOGGER = LoggerFactory.getLogger(CartService.class);
26 | private static final String REDIS_KEY_PRE_CART = "cart_";
27 |
28 | @Autowired
29 | private RedisTemplate redisTemplate;
30 |
31 | public List getProductsByUsername(String username) {
32 | try {
33 | List records = redisTemplate.opsForList().range(REDIS_KEY_PRE_CART + username, 0, -1);
34 | LOGGER.info("get products by username: {}, result: {}", username, records);
35 | return records;
36 | } catch (Exception e) {
37 | LOGGER.warn("redis err ", e);
38 | return Collections.emptyList();
39 | }
40 | }
41 |
42 | public Result addProductToCart(CartRecord cartRecord) {
43 | try {
44 | LOGGER.info("add product to cart, cartRecord: {}", cartRecord);
45 | String key = REDIS_KEY_PRE_CART + cartRecord.getUsername();
46 | ListOperations optList = redisTemplate.opsForList();
47 | List records = optList.range(key, 0, -1);
48 | boolean found = false;
49 | for (int i = 0; i < records.size(); i++) {
50 | CartRecord cur = records.get(i);
51 | if (cur.getProductId().equals(cartRecord.getProductId())) {
52 | cur.setCount(cur.getCount() + 1);
53 | optList.set(key, i, cur);
54 | found = true;
55 | break;
56 | }
57 | }
58 | if (!found) {
59 | redisTemplate.opsForList().leftPush(REDIS_KEY_PRE_CART + cartRecord.getUsername(), cartRecord)
60 | .intValue();
61 | }
62 | return new Result(ResultEnum.SUCCESS);
63 | } catch (Exception e) {
64 | LOGGER.warn("redis err ", e);
65 | Result rs = new Result<>(ResultEnum.ERROR);
66 | rs.setData(e.toString());
67 | return rs;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/cart-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: eshop-cart-service
4 | redis:
5 | host: 192.168.18.134
6 | port: 6379
7 | #password:
8 | info:
9 | app:
10 | name: ${spring.application.name}
11 | version: v1.0.0
12 | server:
13 | port: 8035
14 | context-path: /
15 | tomcat:
16 | uri-encoding: UTF-8
17 |
18 | logging:
19 | config: classpath:logback.xml
20 | eureka:
21 | instance:
22 | hostname: 127.0.0.1
23 | prefer-ip-address: true
24 | client:
25 | healthcheck:
26 | enabled: true
27 | registerWithEureka: true
28 | fetchRegistry: true
29 | service-url:
30 | defaultZone: http://127.0.0.1:8030/eureka/
31 |
--------------------------------------------------------------------------------
/cart-service/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/config/zuul/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: micro-gateway
4 | redis:
5 | host: 192.168.18.134
6 | port: 6379
7 | #password:
8 | info:
9 | app:
10 | name: ${spring.application.name}
11 | version: v1.0.0
12 | server:
13 | port: 8039
14 | context-path: /
15 | tomcat:
16 | uri-encoding: UTF-8
17 |
18 | logging:
19 | config: classpath:logback.xml
20 | eureka:
21 | instance:
22 | hostname: 127.0.0.1
23 | prefer-ip-address: true
24 | client:
25 | healthcheck:
26 | enabled: true
27 | registerWithEureka: true
28 | fetchRegistry: true
29 | service-url:
30 | defaultZone: http://127.0.0.1:8030/eureka/
31 |
32 | zuul:
33 | ribbon-isolation-strategy: THREAD # SEMAPHORE THREAD
34 | sensitive-headers:
35 | ignored-headers:
36 | ignored-services: '*'
37 | retryable: true
38 | routes:
39 | session:
40 | path: /session/**
41 | url: forward:/session
42 | account:
43 | path: /account/**
44 | serviceId: eshop-auth-service
45 | stripPrefix: false
46 | product:
47 | path: /products/**
48 | serviceId: eshop-product-service
49 | stripPrefix: false
50 | cart:
51 | path: /cart/**
52 | serviceId: eshop-cart-service
53 | stripPrefix: false
54 |
55 | hystrix:
56 | command:
57 | default:
58 | execution:
59 | isolation:
60 | thread:
61 | timeoutInMilliseconds: 10000
62 |
63 | ribbon:
64 | MaxAutoRetries: 2
65 | MaxAutoRetriesNextServer: 3
66 | restclient:
67 | enabled: true
--------------------------------------------------------------------------------
/eshop-web/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 |
6 | Springcloud_eShop
7 | Springcloud_eShop
8 | 0.0.1-SNAPSHOT
9 |
10 | sc_eshop_web
11 | sc_eshop_web
12 | jar
13 |
14 | 9.5.1
15 |
16 |
17 |
18 | org.springframework.boot
19 | spring-boot-starter-web
20 |
21 |
22 | org.springframework.cloud
23 | spring-cloud-starter-eureka
24 | ${spring.cloud.version}
25 |
26 |
27 | org.springframework.cloud
28 | spring-cloud-starter-feign
29 | ${spring.cloud.version}
30 |
31 |
32 | org.springframework.cloud
33 | spring-cloud-starter-hystrix
34 | ${spring.cloud.version}
35 |
36 |
37 | com.google.guava
38 | guava
39 | 23.0
40 |
41 |
42 |
43 |
44 | eshop_sc_eshop_web
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-maven-plugin
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/App.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.cloud.client.SpringCloudApplication;
5 | import org.springframework.cloud.netflix.feign.EnableFeignClients;
6 |
7 | /**
8 | * Desc:
9 | *
10 | * @date: 27/08/2017
11 | * @author: Leader us
12 | */
13 | @EnableFeignClients
14 | @SpringCloudApplication
15 | public class App{
16 | public static final String SESSION_KEY = "SESSION";
17 |
18 | public static void main(String[] args) {
19 | SpringApplication.run(App.class, args);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/JacksonUtil.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.core.JsonParser;
5 | import com.fasterxml.jackson.core.Version;
6 | import com.fasterxml.jackson.databind.DeserializationFeature;
7 | import com.fasterxml.jackson.databind.JavaType;
8 | import com.fasterxml.jackson.databind.ObjectMapper;
9 | import com.fasterxml.jackson.databind.SerializationFeature;
10 | import com.fasterxml.jackson.databind.module.SimpleModule;
11 | import org.apache.commons.lang.StringUtils;
12 |
13 | import java.util.List;
14 | /**
15 | * Desc:
16 | *
17 | * @date: 27/08/2017
18 | * @author: Leader us
19 | */
20 | public class JacksonUtil {
21 | private final static ObjectMapper objectMapper = new ObjectMapper();
22 |
23 | static {
24 | SimpleModule simpleModule = new SimpleModule("SimpleJodaModule", new Version(1, 0, 0, null, null, null));
25 | objectMapper.registerModule(simpleModule);
26 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
27 | objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
28 | objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
29 | objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
30 | objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
31 | objectMapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
32 | objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
33 | objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
34 | }
35 |
36 | public static String encode(Object obj) {
37 | try {
38 | return objectMapper.writeValueAsString(obj);
39 | } catch (Exception ignored) {
40 | }
41 | return null;
42 | }
43 |
44 | /**
45 | * 将json string反序列化成对象
46 | *
47 | * @param json
48 | * @param valueType
49 | * @return
50 | */
51 | public static T decode(String json, Class valueType) {
52 | if (StringUtils.isEmpty(json)) {
53 | return null;
54 | }
55 | try {
56 | return objectMapper.readValue(json, valueType);
57 | } catch (Exception ignored) {
58 | }
59 | return null;
60 | }
61 |
62 | public static List decodeList(String json, Class valueType) {
63 | try {
64 | JavaType javaType = getCollectionType(List.class, valueType);
65 | return (List) objectMapper.readValue(json, javaType);
66 | } catch (Exception ignored) {
67 | }
68 | return null;
69 | }
70 |
71 | private static JavaType getCollectionType(Class> collectionClass, Class>... elementClasses) {
72 | return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/config/SecurityConfig.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.config;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
7 |
8 | @Configuration
9 | public class SecurityConfig extends WebMvcConfigurerAdapter {
10 | @Autowired
11 | SecurityInterceptor inteseptor;
12 | @Override
13 | public void addInterceptors(InterceptorRegistry registry) {
14 | registry.addInterceptor(inteseptor).excludePathPatterns("/error","/login.html", "/account/login",
15 | "/session/**", "/detail.html").addPathPatterns("/","/**");
16 |
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/config/SecurityInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.config;
2 |
3 | import java.io.IOException;
4 | import java.util.Map;
5 | import java.util.Optional;
6 | import java.util.stream.Stream;
7 |
8 | import javax.servlet.ServletException;
9 | import javax.servlet.http.Cookie;
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 |
13 | import org.apache.commons.lang.ArrayUtils;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.context.ApplicationContext;
18 | import org.springframework.context.event.ContextRefreshedEvent;
19 | import org.springframework.context.event.EventListener;
20 | import org.springframework.stereotype.Component;
21 | import org.springframework.web.servlet.HandlerInterceptor;
22 | import org.springframework.web.servlet.ModelAndView;
23 |
24 | import com.google.common.collect.Maps;
25 | import com.mycat.monoeshop.App;
26 | import com.mycat.monoeshop.model.Result;
27 | import com.mycat.monoeshop.service.rest.SessionService;
28 |
29 | /**
30 | * Desc:
31 | *
32 | * @date: 27/08/2017
33 | * @author: Leader us
34 | */
35 | @Component
36 | public class SecurityInterceptor implements HandlerInterceptor {
37 | private static final Logger LOGGER = LoggerFactory.getLogger(SecurityInterceptor.class);
38 | private static final String REDIRECT_PAGE = "/login.html";
39 | ApplicationContext applicationContext;
40 |
41 | @EventListener
42 | public void setApplicationContext(ContextRefreshedEvent event) {
43 | applicationContext = event.getApplicationContext();
44 | }
45 |
46 | SessionService sessionService;
47 |
48 | @Override
49 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
50 | throws Exception {
51 | Cookie[] cookies = request.getCookies();
52 | if (ArrayUtils.isEmpty(cookies)) {
53 | LOGGER.warn("no cookie ,to login ," + request.getRequestURL());
54 | response.sendRedirect(REDIRECT_PAGE);
55 | return false;
56 | }
57 | Optional opt = Stream.of(cookies)
58 | .filter(cookie -> cookie != null && App.SESSION_KEY.equals(cookie.getName())).findFirst();
59 |
60 | if (opt.isPresent()) {
61 | Cookie cookie = opt.get();
62 | String token = cookie.getValue();
63 | LOGGER.info("check SESSION_KEY cookie " + token);
64 | try {
65 | Result sessionResult = getSessionSrv().tokenCheck("SESSION=" + token);
66 | if (sessionResult != null && sessionResult.getCode() == SessionService.RESULT_SUCCESS) {
67 | return true;
68 | }
69 | } catch (Exception e) {
70 | LOGGER.warn("check token error", e);
71 | }
72 | }
73 | LOGGER.warn("no SESSION_KEY cookie ,to login ");
74 | response.sendRedirect(REDIRECT_PAGE);
75 | return false;
76 | }
77 |
78 | private SessionService getSessionSrv()
79 | {
80 | if(sessionService!=null)
81 | {
82 | return sessionService;
83 | }else
84 | {
85 | sessionService=this.applicationContext.getBean(SessionService.class);
86 | return sessionService;
87 | } }
88 |
89 | @Override
90 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
91 | ModelAndView modelAndView) throws Exception {
92 |
93 | }
94 |
95 | @Override
96 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
97 | throws Exception {
98 |
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/controller/AccountController.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.controller;
2 |
3 | import java.io.IOException;
4 |
5 | import javax.servlet.http.Cookie;
6 | import javax.servlet.http.HttpServletResponse;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RequestMethod;
14 |
15 | import com.mycat.monoeshop.App;
16 | import com.mycat.monoeshop.service.rest.AccountService;
17 |
18 | /**
19 | * Desc:
20 | *
21 | * @date: 27/08/2017
22 | * @author: Leader us
23 | */
24 | @Controller
25 | @RequestMapping("/account")
26 | public class AccountController {
27 | @Autowired
28 | private AccountService accountService;
29 | private static final Logger LOGGER = LoggerFactory.getLogger(AccountService.class);
30 | @RequestMapping(value = "login", method = RequestMethod.POST)
31 | public void login(HttpServletResponse response, String username, String password) throws IOException {
32 | LOGGER.info("login handle "+username);
33 | String token = accountService.login(username, password);
34 | if (token != null) {
35 | Cookie cookie = new Cookie(App.SESSION_KEY, token);
36 | cookie.setMaxAge(24 * 60 * 60);
37 | cookie.setPath("/");
38 | response.addCookie(cookie);
39 | LOGGER.info("redirect to main.html ");
40 | response.sendRedirect("/main.html");
41 | //return "redirect:/main.html";
42 | } else {
43 | response.sendRedirect("/login.html");
44 | //return "redirect:";
45 | }
46 | }
47 |
48 | @RequestMapping(value = "/")
49 | public String index() {
50 | return "/main.html";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/controller/CartController.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.controller;
2 |
3 | import java.util.List;
4 |
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Controller;
9 | import org.springframework.web.bind.annotation.CookieValue;
10 | import org.springframework.web.bind.annotation.RequestBody;
11 | import org.springframework.web.bind.annotation.RequestMapping;
12 | import org.springframework.web.bind.annotation.ResponseBody;
13 |
14 | import com.mycat.monoeshop.App;
15 | import com.mycat.monoeshop.model.CartRecord;
16 | import com.mycat.monoeshop.model.Result;
17 | import com.mycat.monoeshop.service.rest.CartService;
18 |
19 | /**
20 | * Desc:
21 | *
22 | * @date: 27/08/2017
23 | * @author: Leader us
24 | */
25 | @Controller
26 | @RequestMapping("/cart")
27 | public class CartController {
28 | private static final Logger LOGGER = LoggerFactory.getLogger(CartController.class);
29 |
30 | @Autowired
31 | private CartService cartService;
32 |
33 | @RequestMapping("records")
34 | @ResponseBody
35 | public List getProductsByUsername(@CookieValue(App.SESSION_KEY) String sessionId) {
36 | LOGGER.info("get cart for user " + sessionId);
37 | return cartService.getProductsByUsername("SESSION="+sessionId);
38 | }
39 |
40 | @RequestMapping("add-cart")
41 | @ResponseBody
42 | public Result addProductToCart(@CookieValue(App.SESSION_KEY) String sessionId,
43 | @RequestBody CartRecord cartRecord) {
44 | cartRecord.setUsername(sessionId);
45 | LOGGER.info("add goods to cart " + cartRecord);
46 | return cartService.addProductToCart("SESSION="+sessionId, cartRecord);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/controller/Mainpage.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.controller;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 |
6 | /**
7 | * Desc:
8 | *
9 | * @date: 27/08/2017
10 | * @author: Leader us
11 | */
12 | @Controller
13 | public class Mainpage {
14 | @RequestMapping("/")
15 | public String index()
16 | {
17 | return "/main.html";
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/controller/ProductController.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.controller;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.ResponseBody;
10 |
11 | import com.mycat.monoeshop.model.Product;
12 | import com.mycat.monoeshop.service.rest.ProductService;
13 |
14 | /**
15 | * Desc:
16 | *
17 | * @date: 27/08/2017
18 | * @author: Leader us
19 | */
20 | @Controller
21 | @RequestMapping("/products")
22 | public class ProductController {
23 | @Autowired
24 | private ProductService productService;
25 |
26 | @RequestMapping("")
27 | @ResponseBody
28 | public List getProducts() {
29 | return productService.getProducts();
30 | }
31 |
32 | @RequestMapping("{id}")
33 | @ResponseBody
34 | public Product getProductById(@PathVariable Integer id) {
35 | return productService.getProductById(id);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/model/Account.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public class Account {
10 | private String name;
11 | private String password;
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | public void setName(String name) {
18 | this.name = name;
19 | }
20 |
21 | public String getPassword() {
22 | return password;
23 | }
24 |
25 | public void setPassword(String password) {
26 | this.password = password;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/model/CartRecord.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | import java.math.BigDecimal;
4 | import java.util.Date;
5 |
6 | /**
7 | * Desc:
8 | *
9 | * @date: 27/08/2017
10 | * @author: Leader us
11 | */
12 | public class CartRecord {
13 | private Integer productId;
14 | private String productName;
15 | private BigDecimal productPrice;
16 | private String username;
17 | private Date time;
18 | private Integer count;
19 |
20 | public Integer getProductId() {
21 | return productId;
22 | }
23 |
24 | public void setProductId(Integer productId) {
25 | this.productId = productId;
26 | }
27 |
28 | public String getProductName() {
29 | return productName;
30 | }
31 |
32 | public void setProductName(String productName) {
33 | this.productName = productName;
34 | }
35 |
36 | public BigDecimal getProductPrice() {
37 | return productPrice;
38 | }
39 |
40 | public void setProductPrice(BigDecimal productPrice) {
41 | this.productPrice = productPrice;
42 | }
43 |
44 | public String getUsername() {
45 | return username;
46 | }
47 |
48 | public void setUsername(String username) {
49 | this.username = username;
50 | }
51 |
52 | public Date getTime() {
53 | return time;
54 | }
55 |
56 | public void setTime(Date time) {
57 | this.time = time;
58 | }
59 |
60 | public Integer getCount() {
61 | return count;
62 | }
63 |
64 | public void setCount(Integer count) {
65 | this.count = count;
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return "CartRecord{" +
71 | "productId='" + productId + '\'' +
72 | ", productName='" + productName + '\'' +
73 | ", productPrice=" + productPrice +
74 | ", username='" + username + '\'' +
75 | ", time=" + time +
76 | ", count=" + count +
77 | '}';
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/model/Product.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | import java.math.BigDecimal;
4 |
5 | /**
6 | * Desc:
7 | *
8 | * @date: 27/08/2017
9 | * @author: Leader us
10 | */
11 | public class Product {
12 | private Integer id;
13 | private String name;
14 | private BigDecimal price;
15 | private String desc;
16 |
17 | public Integer getId() {
18 | return id;
19 | }
20 |
21 | public void setId(Integer id) {
22 | this.id = id;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 |
33 | public BigDecimal getPrice() {
34 | return price;
35 | }
36 |
37 | public void setPrice(BigDecimal price) {
38 | this.price = price;
39 | }
40 |
41 | public String getDesc() {
42 | return desc;
43 | }
44 |
45 | public void setDesc(String desc) {
46 | this.desc = desc;
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "Product{" +
52 | "id=" + id +
53 | ", name='" + name + '\'' +
54 | ", price=" + price +
55 | ", desc='" + desc + '\'' +
56 | '}';
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/model/Result.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public class Result {
10 | private int code;
11 | private String desc;
12 | private T data;
13 |
14 | public Result()
15 | {
16 |
17 | }
18 | public Result(ResultEnum resultEnum) {
19 | this.code = resultEnum.getCode();
20 | this.desc = resultEnum.getDesc();
21 | }
22 |
23 | public Result(ResultEnum resultEnum, T data) {
24 | this.code = resultEnum.getCode();
25 | this.desc = resultEnum.getDesc();
26 | this.data = data;
27 | }
28 |
29 | public int getCode() {
30 | return code;
31 | }
32 |
33 | public void setCode(int code) {
34 | this.code = code;
35 | }
36 |
37 | public String getDesc() {
38 | return desc;
39 | }
40 |
41 | public void setDesc(String desc) {
42 | this.desc = desc;
43 | }
44 |
45 | public T getData() {
46 | return data;
47 | }
48 |
49 | public void setData(T data) {
50 | this.data = data;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/model/ResultEnum.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public enum ResultEnum {
10 | SUCCESS(200, "success"), ERROR(502, "error"), NOT_LOGIN(503, "not login");
11 |
12 | private int code;
13 | private String desc;
14 |
15 | ResultEnum(int code, String desc) {
16 | this.code = code;
17 | this.desc = desc;
18 | }
19 |
20 | public int getCode() {
21 | return code;
22 | }
23 |
24 | public String getDesc() {
25 | return desc;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/service/rest/AccountService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.service.rest;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.cloud.netflix.feign.FeignClient;
6 | import org.springframework.stereotype.Component;
7 | import org.springframework.web.bind.annotation.PostMapping;
8 | import org.springframework.web.bind.annotation.RequestParam;
9 |
10 | /**
11 | * Desc:
12 | *
13 | * @date: 27/08/2017
14 | * @author: Leader us
15 | */
16 | @FeignClient(name = "micro-gateway", fallback = AccountService.HystrixAccountService.class)
17 | public interface AccountService {
18 | @PostMapping("/account/login")
19 | String login(@RequestParam("username") String username, @RequestParam("password") String password);
20 |
21 | @Component
22 | class HystrixAccountService implements AccountService {
23 | private static final Logger LOGGER = LoggerFactory.getLogger(AccountService.class);
24 | @Override
25 | public String login(String username, String password) {
26 | LOGGER.warn("Hystrix occured: login ");
27 | return null;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/service/rest/CartService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.service.rest;
2 |
3 | import java.math.BigDecimal;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.cloud.netflix.feign.FeignClient;
10 | import org.springframework.stereotype.Component;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.PathVariable;
13 | import org.springframework.web.bind.annotation.RequestBody;
14 | import org.springframework.web.bind.annotation.RequestHeader;
15 |
16 | import com.mycat.monoeshop.model.CartRecord;
17 | import com.mycat.monoeshop.model.Result;
18 |
19 | /**
20 | * Desc:
21 | *
22 | * @date: 27/08/2017
23 | * @author: Leader us
24 | */
25 |
26 | @FeignClient(name = "micro-gateway", fallback = CartService.HystrixCartService.class)
27 | public interface CartService {
28 |
29 | @GetMapping("/cart/add-cart")
30 | Result addProductToCart(@RequestHeader("Cookie") String sessionId,@RequestBody CartRecord cartRecord);
31 |
32 | @GetMapping("/cart/records")
33 | List getProductsByUsername(@RequestHeader("Cookie") String sessionId);
34 |
35 | @Component
36 | class HystrixCartService implements CartService {
37 | private static final Logger LOGGER = LoggerFactory.getLogger(CartService.class);
38 | @Override
39 | public List getProductsByUsername(@RequestHeader("Cookie") String sessionId) {
40 | LOGGER.warn("Hystrix occured :CartRecord");
41 | CartRecord prod=new CartRecord();
42 | prod.setCount(0);
43 | prod.setProductId(0);
44 | prod.setProductName("Error");
45 | prod.setProductPrice(BigDecimal.ZERO);
46 | ArrayList rest=new ArrayList<>();
47 | rest.add(prod);
48 | return rest;
49 | }
50 |
51 | @Override
52 | public Result addProductToCart(@RequestHeader("Cookie") String sessionId,CartRecord cartRecord) {
53 | LOGGER.warn("Hystrix occured :addProductToCart");
54 | return new Result(com.mycat.monoeshop.model.ResultEnum.ERROR);
55 | }
56 |
57 | }
58 | }
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/service/rest/ProductService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.service.rest;
2 |
3 | import java.math.BigDecimal;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.cloud.netflix.feign.FeignClient;
10 | import org.springframework.stereotype.Component;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.PathVariable;
13 |
14 | import com.mycat.monoeshop.model.Product;
15 |
16 | /**
17 | * Desc:
18 | *
19 | * @date: 27/08/2017
20 | * @author: Leader us
21 | */
22 |
23 | @FeignClient(name = "micro-gateway", fallback = ProductService.HystrixProductService.class)
24 | public interface ProductService {
25 |
26 | @GetMapping("/products/all")
27 | List getProducts();
28 |
29 | @GetMapping("/products/{id}")
30 | Product getProductById(@PathVariable("id") Integer id);
31 |
32 | @Component
33 | class HystrixProductService implements ProductService {
34 | Logger LOGGER = LoggerFactory.getLogger(ProductService.class);
35 |
36 | @Override
37 | public List getProducts() {
38 | LOGGER.warn("Hystrix occured: getProducts");
39 | Product prod = new Product();
40 | prod.setId(0);
41 | prod.setName("Error");
42 | prod.setPrice(BigDecimal.ZERO);
43 | prod.setDesc("Erro occured");
44 | ArrayList rest = new ArrayList<>();
45 | rest.add(prod);
46 | return rest;
47 | }
48 |
49 | @Override
50 | public Product getProductById(Integer id) {
51 | LOGGER.warn("Hystrix occured: getProductById");
52 | return null;
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/eshop-web/src/main/java/com/mycat/monoeshop/service/rest/SessionService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.service.rest;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.cloud.netflix.feign.FeignClient;
6 | import org.springframework.stereotype.Component;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.RequestHeader;
9 |
10 | import com.mycat.monoeshop.model.Result;
11 | import com.mycat.monoeshop.model.ResultEnum;
12 |
13 | /**
14 | * Desc:
15 | *
16 | * @date: 27/08/2017
17 | * @author: Leader us
18 | */
19 | @FeignClient(name = "micro-gateway", fallback = SessionService.HystrixSessionService.class)
20 | public interface SessionService {
21 | Logger LOGGER = LoggerFactory.getLogger(SessionService.class);
22 | public static final int RESULT_SUCCESS = 200;
23 | @GetMapping(value = "/session/token")
24 | Result tokenCheck(@RequestHeader("Cookie") String sessionId);
25 |
26 | @Component
27 | class HystrixSessionService implements SessionService {
28 | @Override
29 | public Result tokenCheck(String sessionId) {
30 | LOGGER.warn("token check error");
31 | return new Result(ResultEnum.ERROR);
32 | }
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: eshop-web
4 | info:
5 | app:
6 | name: ${spring.application.name}
7 | version: v1.0.0
8 | server:
9 | port: 8033
10 | context-path: /
11 | tomcat:
12 | uri-encoding: UTF-8
13 |
14 | logging:
15 | config: classpath:logback.xml
16 | eureka:
17 | instance:
18 | hostname: 127.0.0.1
19 | prefer-ip-address: true
20 | client:
21 | healthcheck:
22 | enabled: true
23 | registerWithEureka: false
24 | fetchRegistry: true
25 | service-url:
26 | defaultZone: http://127.0.0.1:8030/eureka/
27 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/cart.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | My Shop Plantform
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/bootstrap-table.min.css:
--------------------------------------------------------------------------------
1 | .fixed-table-container .bs-checkbox,.fixed-table-container .no-records-found{text-align:center}.fixed-table-body thead th .th-inner,.table td,.table th{box-sizing:border-box}.bootstrap-table .table{margin-bottom:0!important;border-bottom:1px solid #ddd;border-collapse:collapse!important;border-radius:1px}.bootstrap-table .table:not(.table-condensed),.bootstrap-table .table:not(.table-condensed)>tbody>tr>td,.bootstrap-table .table:not(.table-condensed)>tbody>tr>th,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>td,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>th,.bootstrap-table .table:not(.table-condensed)>thead>tr>td{padding:8px}.bootstrap-table .table.table-no-bordered>tbody>tr>td,.bootstrap-table .table.table-no-bordered>thead>tr>th{border-right:2px solid transparent}.bootstrap-table .table.table-no-bordered>tbody>tr>td:last-child{border-right:none}.fixed-table-container{position:relative;clear:both;border:1px solid #ddd;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px}.fixed-table-container.table-no-bordered{border:1px solid transparent}.fixed-table-footer,.fixed-table-header{overflow:hidden}.fixed-table-footer{border-top:1px solid #ddd}.fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.fixed-table-container table{width:100%}.fixed-table-container thead th{height:0;padding:0;margin:0;border-left:1px solid #ddd}.fixed-table-container thead th:focus{outline:transparent solid 0}.fixed-table-container thead th:first-child{border-left:none;border-top-left-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px}.fixed-table-container tbody td .th-inner,.fixed-table-container thead th .th-inner{padding:8px;line-height:24px;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fixed-table-container thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.fixed-table-container thead th .both{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC')}.fixed-table-container thead th .asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==)}.fixed-table-container thead th .desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=)}.fixed-table-container th.detail{width:30px}.fixed-table-container tbody td{border-left:1px solid #ddd}.fixed-table-container tbody tr:first-child td{border-top:none}.fixed-table-container tbody td:first-child{border-left:none}.fixed-table-container tbody .selected td{background-color:#f5f5f5}.fixed-table-container .bs-checkbox .th-inner{padding:8px 0}.fixed-table-container input[type=radio],.fixed-table-container input[type=checkbox]{margin:0 auto!important}.fixed-table-pagination .pagination-detail,.fixed-table-pagination div.pagination{margin-top:10px;margin-bottom:10px}.fixed-table-pagination div.pagination .pagination{margin:0}.fixed-table-pagination .pagination a{padding:6px 12px;line-height:1.428571429}.fixed-table-pagination .pagination-info{line-height:34px;margin-right:5px}.fixed-table-pagination .btn-group{position:relative;display:inline-block;vertical-align:middle}.fixed-table-pagination .dropup .dropdown-menu{margin-bottom:0}.fixed-table-pagination .page-list{display:inline-block}.fixed-table-toolbar .columns-left{margin-right:5px}.fixed-table-toolbar .columns-right{margin-left:5px}.fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.fixed-table-toolbar .bs-bars,.fixed-table-toolbar .columns,.fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px;line-height:34px}.fixed-table-pagination li.disabled a{pointer-events:none;cursor:default}.fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;background-color:#fff;text-align:center}.fixed-table-body .card-view .title{font-weight:700;display:inline-block;min-width:30%;text-align:left!important}.table td,.table th{vertical-align:middle}.fixed-table-toolbar .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.fixed-table-toolbar .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.fixed-table-toolbar .btn-group>.btn-group>.btn{border-radius:0}.fixed-table-toolbar .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.fixed-table-toolbar .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .table>thead>tr>th{vertical-align:bottom;border-bottom:1px solid #ddd}.bootstrap-table .table thead>tr>th{padding:0;margin:0}.bootstrap-table .fixed-table-footer tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-footer .table{border-bottom:none;border-radius:0;padding:0!important}.pull-right .dropdown-menu{right:0;left:auto}p.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden}
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.3.7 (http://getbootstrap.com)
3 | * Copyright 2011-2016 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{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:focus,.dropdown-menu>.active>a:hover{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>.active>a,.navbar-default .navbar-nav>.open>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;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>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-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{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:focus,.list-group-item.active:hover{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:focus .badge,.list-group-item.active:hover .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)}
6 | /*# sourceMappingURL=bootstrap-theme.min.css.map */
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/css:
--------------------------------------------------------------------------------
1 | /* cyrillic-ext */
2 | @font-face {
3 | font-family: 'Roboto';
4 | font-style: normal;
5 | font-weight: 100;
6 | src: local('Roboto Thin'), local('Roboto-Thin'), url(http://fonts.gstatic.com/s/roboto/v16/ty9dfvLAziwdqQ2dHoyjphTbgVql8nDJpwnrE27mub0.woff2) format('woff2');
7 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
8 | }
9 | /* cyrillic */
10 | @font-face {
11 | font-family: 'Roboto';
12 | font-style: normal;
13 | font-weight: 100;
14 | src: local('Roboto Thin'), local('Roboto-Thin'), url(http://fonts.gstatic.com/s/roboto/v16/frNV30OaYdlFRtH2VnZZdhTbgVql8nDJpwnrE27mub0.woff2) format('woff2');
15 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
16 | }
17 | /* greek-ext */
18 | @font-face {
19 | font-family: 'Roboto';
20 | font-style: normal;
21 | font-weight: 100;
22 | src: local('Roboto Thin'), local('Roboto-Thin'), url(http://fonts.gstatic.com/s/roboto/v16/gwVJDERN2Amz39wrSoZ7FxTbgVql8nDJpwnrE27mub0.woff2) format('woff2');
23 | unicode-range: U+1F00-1FFF;
24 | }
25 | /* greek */
26 | @font-face {
27 | font-family: 'Roboto';
28 | font-style: normal;
29 | font-weight: 100;
30 | src: local('Roboto Thin'), local('Roboto-Thin'), url(http://fonts.gstatic.com/s/roboto/v16/aZMswpodYeVhtRvuABJWvBTbgVql8nDJpwnrE27mub0.woff2) format('woff2');
31 | unicode-range: U+0370-03FF;
32 | }
33 | /* vietnamese */
34 | @font-face {
35 | font-family: 'Roboto';
36 | font-style: normal;
37 | font-weight: 100;
38 | src: local('Roboto Thin'), local('Roboto-Thin'), url(http://fonts.gstatic.com/s/roboto/v16/VvXUGKZXbHtX_S_VCTLpGhTbgVql8nDJpwnrE27mub0.woff2) format('woff2');
39 | unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
40 | }
41 | /* latin-ext */
42 | @font-face {
43 | font-family: 'Roboto';
44 | font-style: normal;
45 | font-weight: 100;
46 | src: local('Roboto Thin'), local('Roboto-Thin'), url(http://fonts.gstatic.com/s/roboto/v16/e7MeVAyvogMqFwwl61PKhBTbgVql8nDJpwnrE27mub0.woff2) format('woff2');
47 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
48 | }
49 | /* latin */
50 | @font-face {
51 | font-family: 'Roboto';
52 | font-style: normal;
53 | font-weight: 100;
54 | src: local('Roboto Thin'), local('Roboto-Thin'), url(http://fonts.gstatic.com/s/roboto/v16/2tsd397wLxj96qwHyNIkxPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
55 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
56 | }
57 | /* cyrillic-ext */
58 | @font-face {
59 | font-family: 'Roboto';
60 | font-style: normal;
61 | font-weight: 300;
62 | src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v16/0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
63 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
64 | }
65 | /* cyrillic */
66 | @font-face {
67 | font-family: 'Roboto';
68 | font-style: normal;
69 | font-weight: 300;
70 | src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v16/Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
71 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
72 | }
73 | /* greek-ext */
74 | @font-face {
75 | font-family: 'Roboto';
76 | font-style: normal;
77 | font-weight: 300;
78 | src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v16/-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
79 | unicode-range: U+1F00-1FFF;
80 | }
81 | /* greek */
82 | @font-face {
83 | font-family: 'Roboto';
84 | font-style: normal;
85 | font-weight: 300;
86 | src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v16/I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
87 | unicode-range: U+0370-03FF;
88 | }
89 | /* vietnamese */
90 | @font-face {
91 | font-family: 'Roboto';
92 | font-style: normal;
93 | font-weight: 300;
94 | src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v16/NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
95 | unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
96 | }
97 | /* latin-ext */
98 | @font-face {
99 | font-family: 'Roboto';
100 | font-style: normal;
101 | font-weight: 300;
102 | src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v16/Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
103 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
104 | }
105 | /* latin */
106 | @font-face {
107 | font-family: 'Roboto';
108 | font-style: normal;
109 | font-weight: 300;
110 | src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v16/Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
111 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
112 | }
113 | /* cyrillic-ext */
114 | @font-face {
115 | font-family: 'Roboto';
116 | font-style: normal;
117 | font-weight: 400;
118 | src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v16/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
119 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
120 | }
121 | /* cyrillic */
122 | @font-face {
123 | font-family: 'Roboto';
124 | font-style: normal;
125 | font-weight: 400;
126 | src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v16/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
127 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
128 | }
129 | /* greek-ext */
130 | @font-face {
131 | font-family: 'Roboto';
132 | font-style: normal;
133 | font-weight: 400;
134 | src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v16/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
135 | unicode-range: U+1F00-1FFF;
136 | }
137 | /* greek */
138 | @font-face {
139 | font-family: 'Roboto';
140 | font-style: normal;
141 | font-weight: 400;
142 | src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v16/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
143 | unicode-range: U+0370-03FF;
144 | }
145 | /* vietnamese */
146 | @font-face {
147 | font-family: 'Roboto';
148 | font-style: normal;
149 | font-weight: 400;
150 | src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v16/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
151 | unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
152 | }
153 | /* latin-ext */
154 | @font-face {
155 | font-family: 'Roboto';
156 | font-style: normal;
157 | font-weight: 400;
158 | src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v16/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
159 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
160 | }
161 | /* latin */
162 | @font-face {
163 | font-family: 'Roboto';
164 | font-style: normal;
165 | font-weight: 400;
166 | src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v16/CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2');
167 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
168 | }
169 | /* cyrillic-ext */
170 | @font-face {
171 | font-family: 'Roboto';
172 | font-style: normal;
173 | font-weight: 500;
174 | src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v16/ZLqKeelYbATG60EpZBSDyxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
175 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
176 | }
177 | /* cyrillic */
178 | @font-face {
179 | font-family: 'Roboto';
180 | font-style: normal;
181 | font-weight: 500;
182 | src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v16/oHi30kwQWvpCWqAhzHcCSBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
183 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
184 | }
185 | /* greek-ext */
186 | @font-face {
187 | font-family: 'Roboto';
188 | font-style: normal;
189 | font-weight: 500;
190 | src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v16/rGvHdJnr2l75qb0YND9NyBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
191 | unicode-range: U+1F00-1FFF;
192 | }
193 | /* greek */
194 | @font-face {
195 | font-family: 'Roboto';
196 | font-style: normal;
197 | font-weight: 500;
198 | src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v16/mx9Uck6uB63VIKFYnEMXrRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
199 | unicode-range: U+0370-03FF;
200 | }
201 | /* vietnamese */
202 | @font-face {
203 | font-family: 'Roboto';
204 | font-style: normal;
205 | font-weight: 500;
206 | src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v16/mbmhprMH69Zi6eEPBYVFhRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
207 | unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
208 | }
209 | /* latin-ext */
210 | @font-face {
211 | font-family: 'Roboto';
212 | font-style: normal;
213 | font-weight: 500;
214 | src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v16/oOeFwZNlrTefzLYmlVV1UBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
215 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
216 | }
217 | /* latin */
218 | @font-face {
219 | font-family: 'Roboto';
220 | font-style: normal;
221 | font-weight: 500;
222 | src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v16/RxZJdnzeo3R5zSexge8UUVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
223 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215;
224 | }
225 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/font-awesome.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.3.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('fontawesome-webfont.woff2') format('woff2'),url('fontawesome-webfont.woff2') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leader-us/SpringCloud_eShop/e0da11ba480f7043be40d7a1d1bbd3f0a33ba6ea/eshop-web/src/main/resources/static/css/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/form-elements.css:
--------------------------------------------------------------------------------
1 |
2 | input[type="text"],
3 | input[type="password"],
4 | textarea,
5 | textarea.form-control {
6 | height: 50px;
7 | margin: 0;
8 | padding: 0 20px;
9 | vertical-align: middle;
10 | background: #f8f8f8;
11 | border: 3px solid #ddd;
12 | font-family: 'Roboto', sans-serif;
13 | font-size: 16px;
14 | font-weight: 300;
15 | line-height: 50px;
16 | color: #888;
17 | -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px;
18 | -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none;
19 | -o-transition: all .3s; -moz-transition: all .3s; -webkit-transition: all .3s; -ms-transition: all .3s; transition: all .3s;
20 | }
21 |
22 | textarea,
23 | textarea.form-control {
24 | padding-top: 10px;
25 | padding-bottom: 10px;
26 | line-height: 30px;
27 | }
28 |
29 | input[type="text"]:focus,
30 | input[type="password"]:focus,
31 | textarea:focus,
32 | textarea.form-control:focus {
33 | outline: 0;
34 | background: #fff;
35 | border: 3px solid #ccc;
36 | -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none;
37 | }
38 |
39 | input[type="text"]:-moz-placeholder, input[type="password"]:-moz-placeholder,
40 | textarea:-moz-placeholder, textarea.form-control:-moz-placeholder { color: #888; }
41 |
42 | input[type="text"]:-ms-input-placeholder, input[type="password"]:-ms-input-placeholder,
43 | textarea:-ms-input-placeholder, textarea.form-control:-ms-input-placeholder { color: #888; }
44 |
45 | input[type="text"]::-webkit-input-placeholder, input[type="password"]::-webkit-input-placeholder,
46 | textarea::-webkit-input-placeholder, textarea.form-control::-webkit-input-placeholder { color: #888; }
47 |
48 |
49 |
50 | button.btn {
51 | height: 50px;
52 | margin: 0;
53 | padding: 0 20px;
54 | vertical-align: middle;
55 | background: #4aaf51;
56 | border: 0;
57 | font-family: 'Roboto', sans-serif;
58 | font-size: 16px;
59 | font-weight: 300;
60 | line-height: 50px;
61 | color: #fff;
62 | -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px;
63 | text-shadow: none;
64 | -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none;
65 | -o-transition: all .3s; -moz-transition: all .3s; -webkit-transition: all .3s; -ms-transition: all .3s; transition: all .3s;
66 | }
67 |
68 | button.btn:hover { opacity: 0.6; color: #fff; }
69 |
70 | button.btn:active { outline: 0; opacity: 0.6; color: #fff; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; }
71 |
72 | button.btn:focus { outline: 0; opacity: 0.6; background: #4aaf51; color: #fff; }
73 |
74 | button.btn:active:focus, button.btn.active:focus { outline: 0; opacity: 0.6; background: #4aaf51; color: #fff; }
75 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/product.css:
--------------------------------------------------------------------------------
1 | body{
2 | font-family: 'microsoft yahei',Arial,sans-serif;
3 | color: #898989;
4 | }
5 |
6 | .shape{
7 | border-style: solid; border-width: 0 80px 80px 0; float:right; height: 0px; width: 0px;
8 | -ms-transform:rotate(360deg); /* IE 9 */
9 | -o-transform: rotate(360deg); /* Opera 10.5 */
10 | -webkit-transform:rotate(360deg); /* Safari and Chrome */
11 | transform:rotate(360deg);
12 | }
13 |
14 | .speical{
15 | background:#fff; border:1px solid #ddd; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); margin: 15px 0; overflow:hidden;
16 | }
17 |
18 | .speical:hover {
19 | -webkit-transform: scale(1.1);
20 | -moz-transform: scale(1.1);
21 | -ms-transform: scale(1.1);
22 | -o-transform: scale(1.1);
23 | transform:rotate scale(1.1);
24 | -webkit-transition: all 0.4s ease-in-out;
25 | -moz-transition: all 0.4s ease-in-out;
26 | -o-transition: all 0.4s ease-in-out;
27 | transition: all 0.4s ease-in-out;
28 | }
29 |
30 | .shape {
31 | border-color: rgba(255,255,255,0) #d9534f rgba(255,255,255,0) rgba(255,255,255,0);
32 | }
33 |
34 | .speical-default{
35 | border: 1px solid #d9534f;
36 | }
37 |
38 | .speical-radius{
39 | border-radius:5px;
40 | }
41 |
42 | .shape-text{
43 | color:#fff; font-size:14px; position:relative; right:-45px; top:2px; white-space: nowrap;
44 | -ms-transform:rotate(45deg); /* IE 9 */
45 | -o-transform: rotate(45deg); /* Opera 10.5 */
46 | -webkit-transform:rotate(45deg); /* Safari and Chrome */
47 | transform:rotate(45deg);
48 | }
49 |
50 | .text-special-default{
51 | color:#d9534f;
52 | }
53 |
54 | .speical-content{
55 | padding:0 20px 10px;
56 | }
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/style-responsive.css:
--------------------------------------------------------------------------------
1 | @media (min-width: 980px) {
2 | /*-----*/
3 | .custom-bar-chart {
4 | margin-bottom: 40px;
5 | }
6 |
7 | }
8 |
9 | @media (min-width: 768px) and (max-width: 979px) {
10 |
11 | /*-----*/
12 | .custom-bar-chart {
13 | margin-bottom: 40px;
14 | }
15 |
16 | /*chat room*/
17 |
18 |
19 | }
20 |
21 | @media (max-width: 768px) {
22 |
23 | .header {
24 | position: absolute;
25 | }
26 |
27 | /*sidebar*/
28 |
29 | #sidebar {
30 | height: auto;
31 | overflow: hidden;
32 | position: absolute;
33 | width: 100%;
34 | z-index: 1001;
35 | }
36 |
37 |
38 | /* body container */
39 | #main-content {
40 | margin: 0px!important;
41 | position: none !important;
42 | }
43 |
44 | #sidebar > ul > li > a > span {
45 | line-height: 35px;
46 | }
47 |
48 | #sidebar > ul > li {
49 | margin: 0 10px 5px 10px;
50 | }
51 | #sidebar > ul > li > a {
52 | height:35px;
53 | line-height:35px;
54 | padding: 0 10px;
55 | text-align: left;
56 | }
57 | #sidebar > ul > li > a i{
58 | /*display: none !important;*/
59 | }
60 |
61 | #sidebar ul > li > a .arrow, #sidebar > ul > li > a .arrow.open {
62 | margin-right: 10px;
63 | margin-top: 15px;
64 | }
65 |
66 | #sidebar ul > li.active > a .arrow, #sidebar ul > li > a:hover .arrow, #sidebar ul > li > a:focus .arrow,
67 | #sidebar > ul > li.active > a .arrow.open, #sidebar > ul > li > a:hover .arrow.open, #sidebar > ul > li > a:focus .arrow.open{
68 | margin-top: 15px;
69 | }
70 |
71 | #sidebar > ul > li > a, #sidebar > ul > li > ul.sub > li {
72 | width: 100%;
73 | }
74 | #sidebar > ul > li > ul.sub > li > a {
75 | background: transparent !important ;
76 | }
77 | #sidebar > ul > li > ul.sub > li > a:hover {
78 |
79 | }
80 |
81 |
82 | /* sidebar */
83 | #sidebar {
84 | margin: 0px !important;
85 | }
86 |
87 | /* sidebar collabler */
88 | #sidebar .btn-navbar.collapsed .arrow {
89 | display: none;
90 | }
91 |
92 | #sidebar .btn-navbar .arrow {
93 | position: absolute;
94 | right: 35px;
95 | width: 0;
96 | height: 0;
97 | top:48px;
98 | border-bottom: 15px solid #282e36;
99 | border-left: 15px solid transparent;
100 | border-right: 15px solid transparent;
101 | }
102 |
103 |
104 | /*---------*/
105 |
106 | .modal-footer .btn {
107 | margin-bottom: 0px !important;
108 | }
109 |
110 | .btn {
111 | margin-bottom: 5px;
112 | }
113 |
114 |
115 | /* full calendar fix */
116 | .fc-header-right {
117 | left:25px;
118 | position: absolute;
119 | }
120 |
121 | .fc-header-left .fc-button {
122 | margin: 0px !important;
123 | top: -10px !important;
124 | }
125 |
126 | .fc-header-right .fc-button {
127 | margin: 0px !important;
128 | top: -50px !important;
129 | }
130 |
131 | .fc-state-active, .fc-state-active .fc-button-inner, .fc-state-hover, .fc-state-hover .fc-button-inner {
132 | background: none !important;
133 | color: #FFFFFF !important;
134 | }
135 |
136 | .fc-state-default, .fc-state-default .fc-button-inner {
137 | background: none !important;
138 | }
139 |
140 | .fc-button {
141 | border: none !important;
142 | margin-right: 2px;
143 | }
144 |
145 | .fc-view {
146 | top: 0px !important;
147 | }
148 |
149 | .fc-button .fc-button-inner {
150 | margin: 0px !important;
151 | padding: 2px !important;
152 | border: none !important;
153 | margin-right: 2px !important;
154 | background-color: #fafafa !important;
155 | background-image: -moz-linear-gradient(top, #fafafa, #efefef) !important;
156 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fafafa), to(#efefef)) !important;
157 | background-image: -webkit-linear-gradient(top, #fafafa, #efefef) !important;
158 | background-image: -o-linear-gradient(top, #fafafa, #efefef) !important;
159 | background-image: linear-gradient(to bottom, #fafafa, #efefef) !important;
160 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fafafa', endColorstr='#efefef', GradientType=0) !important;
161 | -webkit-box-shadow: 0 1px 0px rgba(255, 255, 255, .8) !important;
162 | -moz-box-shadow: 0 1px 0px rgba(255, 255, 255, .8) !important;
163 | box-shadow: 0 1px 0px rgba(255, 255, 255, .8) !important;
164 | -webkit-border-radius: 3px !important;
165 | -moz-border-radius: 3px !important;
166 | border-radius: 3px !important;
167 | color: #646464 !important;
168 | border: 1px solid #ddd !important;
169 | text-shadow: 0 1px 0px rgba(255, 255, 255, .6) !important;
170 | text-align: center;
171 | }
172 |
173 | .fc-button.fc-state-disabled .fc-button-inner {
174 | color: #bcbbbb !important;
175 | }
176 |
177 | .fc-button.fc-state-active .fc-button-inner {
178 | background-color: #e5e4e4 !important;
179 | background-image: -moz-linear-gradient(top, #e5e4e4, #dddcdc) !important;
180 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#e5e4e4), to(#dddcdc)) !important;
181 | background-image: -webkit-linear-gradient(top, #e5e4e4, #dddcdc) !important;
182 | background-image: -o-linear-gradient(top, #e5e4e4, #dddcdc) !important;
183 | background-image: linear-gradient(to bottom, #e5e4e4, #dddcdc) !important;
184 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#e5e4e4', endColorstr='#dddcdc', GradientType=0) !important;
185 | }
186 |
187 | .fc-content {
188 | margin-top: 50px;
189 | }
190 |
191 | .fc-header-title h2 {
192 | line-height: 40px !important;
193 | font-size: 12px !important;
194 | }
195 |
196 | .fc-header {
197 | margin-bottom:0px !important;
198 | }
199 |
200 | /*--*/
201 |
202 | /*.chart-position {*/
203 | /*margin-top: 0px;*/
204 | /*}*/
205 |
206 | .stepy-titles li {
207 | margin: 10px 3px;
208 | }
209 |
210 | /*-----*/
211 | .custom-bar-chart {
212 | margin-bottom: 40px;
213 | }
214 |
215 | /*menu icon plus minus*/
216 | .dcjq-icon {
217 | top: 10px;
218 | }
219 | ul.sidebar-menu li ul.sub li a {
220 | padding: 0;
221 | }
222 |
223 | /*---*/
224 |
225 | .img-responsive {
226 | width: 100%;
227 | }
228 |
229 | }
230 |
231 |
232 |
233 | @media (max-width: 480px) {
234 |
235 | .notify-row, .search, .dont-show , .inbox-head .sr-input, .inbox-head .sr-btn{
236 | display: none;
237 | }
238 |
239 | #top_menu .nav > li, ul.top-menu > li {
240 | float: right;
241 | }
242 | .hidden-phone {
243 | display: none !important;
244 | }
245 |
246 | .chart-position {
247 | margin-top: 0px;
248 | }
249 |
250 | .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus {
251 | background-color: #ccc;
252 | border-color:#ccc ;
253 | }
254 |
255 | }
256 |
257 | @media (max-width:320px) {
258 | .login-social-link a {
259 | padding: 15px 17px !important;
260 | }
261 |
262 | .notify-row, .search, .dont-show, .inbox-head .sr-input, .inbox-head .sr-btn {
263 | display: none;
264 | }
265 |
266 | #top_menu .nav > li, ul.top-menu > li {
267 | float: right;
268 | }
269 |
270 | .hidden-phone {
271 | display: none !important;
272 | }
273 |
274 | .chart-position {
275 | margin-top: 0px;
276 | }
277 |
278 | .lock-wrapper {
279 | margin: 10% auto;
280 | max-width: 310px;
281 | }
282 | .lock-input {
283 | width: 82%;
284 | }
285 |
286 | .cmt-form {
287 | display: inline-block;
288 | width: 75%;
289 | }
290 |
291 | }
292 |
293 |
294 |
295 |
296 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/css/style.css:
--------------------------------------------------------------------------------
1 |
2 | body {
3 | font-family: 'Roboto', sans-serif;
4 | font-size: 16px;
5 | font-weight: 300;
6 | color: #888;
7 | line-height: 30px;
8 | text-align: center;
9 | }
10 |
11 | strong {
12 | font-weight: 500;
13 | }
14 |
15 | a, a:hover, a:focus {
16 | color: #4aaf51;
17 | text-decoration: none;
18 | -o-transition: all .3s;
19 | -moz-transition: all .3s;
20 | -webkit-transition: all .3s;
21 | -ms-transition: all .3s;
22 | transition: all .3s;
23 | }
24 |
25 | h1, h2 {
26 | margin-top: 10px;
27 | font-size: 38px;
28 | font-weight: 100;
29 | color: #555;
30 | line-height: 50px;
31 | }
32 |
33 | h3 {
34 | font-size: 22px;
35 | font-weight: 300;
36 | color: #555;
37 | line-height: 30px;
38 | }
39 |
40 | img {
41 | max-width: 100%;
42 | }
43 |
44 | ::-moz-selection {
45 | background: #4aaf51;
46 | color: #fff;
47 | text-shadow: none;
48 | }
49 |
50 | ::selection {
51 | background: #4aaf51;
52 | color: #fff;
53 | text-shadow: none;
54 | }
55 |
56 | .btn-link-1 {
57 | display: inline-block;
58 | height: 50px;
59 | margin: 5px;
60 | padding: 16px 20px 0 20px;
61 | background: #4aaf51;
62 | font-size: 16px;
63 | font-weight: 300;
64 | line-height: 16px;
65 | color: #fff;
66 | -moz-border-radius: 4px;
67 | -webkit-border-radius: 4px;
68 | border-radius: 4px;
69 | }
70 |
71 | .btn-link-1:hover, .btn-link-1:focus, .btn-link-1:active {
72 | outline: 0;
73 | opacity: 0.6;
74 | color: #fff;
75 | }
76 |
77 | .btn-link-1.btn-link-1-facebook {
78 | background: #4862a3;
79 | }
80 |
81 | .btn-link-1.btn-link-1-twitter {
82 | background: #55acee;
83 | }
84 |
85 | .btn-link-1.btn-link-1-google-plus {
86 | background: #dd4b39;
87 | }
88 |
89 | .btn-link-1 i {
90 | padding-right: 5px;
91 | vertical-align: middle;
92 | font-size: 20px;
93 | line-height: 20px;
94 | }
95 |
96 | .btn-link-2 {
97 | display: inline-block;
98 | height: 50px;
99 | margin: 5px;
100 | padding: 15px 20px 0 20px;
101 | background: rgba(0, 0, 0, 0.3);
102 | border: 1px solid #fff;
103 | font-size: 16px;
104 | font-weight: 300;
105 | line-height: 16px;
106 | color: #fff;
107 | -moz-border-radius: 4px;
108 | -webkit-border-radius: 4px;
109 | border-radius: 4px;
110 | }
111 |
112 | .btn-link-2:hover, .btn-link-2:focus,
113 | .btn-link-2:active, .btn-link-2:active:focus {
114 | outline: 0;
115 | opacity: 0.6;
116 | background: rgba(0, 0, 0, 0.3);
117 | color: #fff;
118 | }
119 |
120 | /***** Top content *****/
121 |
122 | .inner-bg {
123 | padding: 100px 0 170px 0;
124 | }
125 |
126 | .top-content .text {
127 | color: #fff;
128 | }
129 |
130 | .top-content .text h1 {
131 | color: #fff;
132 | }
133 |
134 | .top-content .description {
135 | margin: 20px 0 10px 0;
136 | }
137 |
138 | .top-content .description p {
139 | opacity: 0.8;
140 | }
141 |
142 | .top-content .description a {
143 | color: #fff;
144 | }
145 |
146 | .top-content .description a:hover,
147 | .top-content .description a:focus {
148 | border-bottom: 1px dotted #fff;
149 | }
150 |
151 | .form-box {
152 | margin-top: 35px;
153 | }
154 |
155 | .form-top {
156 | overflow: hidden;
157 | padding: 0 25px 15px 25px;
158 | background: #fff;
159 | -moz-border-radius: 4px 4px 0 0;
160 | -webkit-border-radius: 4px 4px 0 0;
161 | border-radius: 4px 4px 0 0;
162 | text-align: left;
163 | }
164 |
165 | .form-top-left {
166 | float: left;
167 | width: 75%;
168 | padding-top: 25px;
169 | }
170 |
171 | .form-top-left h3 {
172 | margin-top: 0;
173 | }
174 |
175 | .form-top-right {
176 | float: left;
177 | width: 25%;
178 | padding-top: 5px;
179 | font-size: 66px;
180 | color: #ddd;
181 | line-height: 100px;
182 | text-align: right;
183 | }
184 |
185 | .form-bottom {
186 | padding: 25px 25px 30px 25px;
187 | background: #eee;
188 | -moz-border-radius: 0 0 4px 4px;
189 | -webkit-border-radius: 0 0 4px 4px;
190 | border-radius: 0 0 4px 4px;
191 | text-align: left;
192 | }
193 |
194 | .form-bottom form textarea {
195 | height: 100px;
196 | }
197 |
198 | .form-bottom form button.btn {
199 | width: 100%;
200 | }
201 |
202 | .form-bottom form .input-error {
203 | border-color: #4aaf51;
204 | }
205 |
206 | .social-login {
207 | margin-top: 35px;
208 | }
209 |
210 | .social-login h3 {
211 | color: #fff;
212 | }
213 |
214 | .social-login-buttons {
215 | margin-top: 25px;
216 | }
217 |
218 | /***** Media queries *****/
219 |
220 | @media (min-width: 992px) and (max-width: 1199px) {
221 | }
222 |
223 | @media (min-width: 768px) and (max-width: 991px) {
224 | }
225 |
226 | @media (max-width: 767px) {
227 |
228 | .inner-bg {
229 | padding: 60px 0 110px 0;
230 | }
231 |
232 | }
233 |
234 | @media (max-width: 415px) {
235 |
236 | h1, h2 {
237 | font-size: 32px;
238 | }
239 |
240 | }
241 |
242 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/detail.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | My Shop Plantform
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leader-us/SpringCloud_eShop/e0da11ba480f7043be40d7a1d1bbd3f0a33ba6ea/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leader-us/SpringCloud_eShop/e0da11ba480f7043be40d7a1d1bbd3f0a33ba6ea/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leader-us/SpringCloud_eShop/e0da11ba480f7043be40d7a1d1bbd3f0a33ba6ea/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leader-us/SpringCloud_eShop/e0da11ba480f7043be40d7a1d1bbd3f0a33ba6ea/eshop-web/src/main/resources/static/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/img/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leader-us/SpringCloud_eShop/e0da11ba480f7043be40d7a1d1bbd3f0a33ba6ea/eshop-web/src/main/resources/static/img/background.jpg
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/bootbox.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * bootbox.js v4.4.0
3 | *
4 | * http://bootboxjs.com/license.txt
5 | */
6 | !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["../../../../../../../../../../Desktop/leader_class/video/全栈/第二季/spring-boot-study/src/main/resources/static/js/jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b, c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a, c, d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d.call(c,a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a, c){var d=0;b.each(a,function(a, b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(e.className=2>=d&&f===d-1?"btn-primary":"btn-default")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"",header:"",footer:"",closeButton:"× ",form:"",inputs:{text:" ",textarea:"",email:" ",select:" ",checkbox:"
",date:" ",time:" ",number:" ",password:" "}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b(" ").attr("label",d.group)),e=o[d.group]),e.append(""+d.text+" ")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("
"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".modal-dialog"),i=d.find(".modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+=""+b.label+" ",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("modal-lg"):"small"===a.size&&f.addClass("modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".modal-backdrop").length&&(a.currentTarget=d.children(".modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p});
7 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/cart.js:
--------------------------------------------------------------------------------
1 | $('.cart_table').bootstrapTable({
2 | url: "/cart/records",
3 | method: "GET",
4 | columns: [{
5 | field: 'productId',
6 | title: 'ID'
7 | }, {
8 | field: 'productName',
9 | title: '商品名称'
10 | }, {
11 | field: 'productPrice',
12 | title: '商品价格'
13 | },{
14 | field: "count",
15 | title: '数量'
16 | }, {
17 | formatter: "amount_formatter",
18 | title: '总额'
19 | }],
20 | responseHandler: handler
21 | });
22 |
23 | function handler(res) {
24 | if (res == undefined) {
25 | return res;
26 | }
27 | var directUrl = res.redirect;
28 | if (directUrl != undefined) {
29 | navi2page(directUrl);
30 | return "[]";
31 | }
32 | return res;
33 | }
34 |
35 |
36 | function amount_formatter(value, row) {
37 | return row.productPrice * row.count;
38 | }
39 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/detail.js:
--------------------------------------------------------------------------------
1 | var id = getQueryString(curPageUrl, 'id');
2 | var dataUrl = "/products/" + id;
3 |
4 | $('.product_detail_table').bootstrapTable({
5 | url: dataUrl,
6 | method: "GET",
7 | columns: [{
8 | field: 'id',
9 | title: 'ID'
10 | }, {
11 | field: 'name',
12 | title: '商品名称'
13 | }, {
14 | field: 'price',
15 | title: '商品价格'
16 | }, {
17 | field: 'desc',
18 | title: '商品描述'
19 | }],
20 | responseHandler: handler
21 | });
22 | function handler(res) {
23 | return res;
24 |
25 | }
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/index.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | navi2page($(".navbar-brand").attr("data-page"));
3 |
4 | $("ul.navbar-nav li").each(function () {
5 | $(this).on("click", function (e) {
6 | var newPage = $(this).attr("data-page");
7 | navi2page(newPage);
8 | })
9 | });
10 |
11 | $(".navbar-brand").on("click", function (e) {
12 | var newPage = $(this).attr("data-page");
13 | navi2page(newPage);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/jquery.backstretch.min.js:
--------------------------------------------------------------------------------
1 | /*! Backstretch - v2.0.4 - 2013-06-19
2 | * http://srobbin.com/jquery-plugins/backstretch/
3 | * Copyright (c) 2013 Scott Robbin; Licensed MIT */
4 | (function(a,d,p){a.fn.backstretch=function(c,b){(c===p||0===c.length)&&a.error("No images were supplied for Backstretch");0===a(d).scrollTop()&&d.scrollTo(0,0);return this.each(function(){var d=a(this),g=d.data("backstretch");if(g){if("string"==typeof c&&"function"==typeof g[c]){g[c](b);return}b=a.extend(g.options,b);g.destroy(!0)}g=new q(this,c,b);d.data("backstretch",g)})};a.backstretch=function(c,b){return a("body").backstretch(c,b).data("backstretch")};a.expr[":"].backstretch=function(c){return a(c).data("backstretch")!==p};a.fn.backstretch.defaults={centeredX:!0,centeredY:!0,duration:5E3,fade:0};var r={left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"100%",width:"100%",zIndex:-999999},s={position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"auto",height:"auto",maxHeight:"none",maxWidth:"none",zIndex:-999999},q=function(c,b,e){this.options=a.extend({},a.fn.backstretch.defaults,e||{});this.images=a.isArray(b)?b:[b];a.each(this.images,function(){a(" ")[0].src=this});this.isBody=c===document.body;this.$container=a(c);this.$root=this.isBody?l?a(d):a(document):this.$container;c=this.$container.children(".backstretch").first();this.$wrap=c.length?c:a('
').css(r).appendTo(this.$container);this.isBody||(c=this.$container.css("position"),b=this.$container.css("zIndex"),this.$container.css({position:"static"===c?"relative":c,zIndex:"auto"===b?0:b,background:"none"}),this.$wrap.css({zIndex:-999998}));this.$wrap.css({position:this.isBody&&l?"fixed":"absolute"});this.index=0;this.show(this.index);a(d).on("resize.backstretch",a.proxy(this.resize,this)).on("orientationchange.backstretch",a.proxy(function(){this.isBody&&0===d.pageYOffset&&(d.scrollTo(0,1),this.resize())},this))};q.prototype={resize:function(){try{var a={left:0,top:0},b=this.isBody?this.$root.width():this.$root.innerWidth(),e=b,g=this.isBody?d.innerHeight?d.innerHeight:this.$root.height():this.$root.innerHeight(),j=e/this.$img.data("ratio"),f;j>=g?(f=(j-g)/2,this.options.centeredY&&(a.top="-"+f+"px")):(j=g,e=j*this.$img.data("ratio"),f=(e-b)/2,this.options.centeredX&&(a.left="-"+f+"px"));this.$wrap.css({width:b,height:g}).find("img:not(.deleteable)").css({width:e,height:j}).css(a)}catch(h){}return this},show:function(c){if(!(Math.abs(c)>this.images.length-1)){var b=this,e=b.$wrap.find("img").addClass("deleteable"),d={relatedTarget:b.$container[0]};b.$container.trigger(a.Event("backstretch.before",d),[b,c]);this.index=c;clearInterval(b.interval);b.$img=a(" ").css(s).bind("load",function(f){var h=this.width||a(f.target).width();f=this.height||a(f.target).height();a(this).data("ratio",h/f);a(this).fadeIn(b.options.speed||b.options.fade,function(){e.remove();b.paused||b.cycle();a(["after","show"]).each(function(){b.$container.trigger(a.Event("backstretch."+this,d),[b,c])})});b.resize()}).appendTo(b.$wrap);b.$img.attr("src",b.images[c]);return b}},next:function(){return this.show(this.indexe||d.operamini&&"[object OperaMini]"==={}.toString.call(d.operamini)||n&&7458>t||-1e||h&&6>h||"palmGetResource"in d&&e&&534>e||-1=k)})(jQuery,window);
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/json2.js:
--------------------------------------------------------------------------------
1 | // json2.js
2 | // 2016-10-28
3 | // Public Domain.
4 | // NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
5 | // See http://www.JSON.org/js.html
6 | // This code should be minified before deployment.
7 | // See http://javascript.crockford.com/jsmin.html
8 |
9 | // USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
10 | // NOT CONTROL.
11 |
12 | // This file creates a global JSON object containing two methods: stringify
13 | // and parse. This file provides the ES5 JSON capability to ES3 systems.
14 | // If a project might run on IE8 or earlier, then this file should be included.
15 | // This file does nothing on ES5 systems.
16 |
17 | // JSON.stringify(value, replacer, space)
18 | // value any JavaScript value, usually an object or array.
19 | // replacer an optional parameter that determines how object
20 | // values are stringified for objects. It can be a
21 | // function or an array of strings.
22 | // space an optional parameter that specifies the indentation
23 | // of nested structures. If it is omitted, the text will
24 | // be packed without extra whitespace. If it is a number,
25 | // it will specify the number of spaces to indent at each
26 | // level. If it is a string (such as "\t" or " "),
27 | // it contains the characters used to indent at each level.
28 | // This method produces a JSON text from a JavaScript value.
29 | // When an object value is found, if the object contains a toJSON
30 | // method, its toJSON method will be called and the result will be
31 | // stringified. A toJSON method does not serialize: it returns the
32 | // value represented by the name/value pair that should be serialized,
33 | // or undefined if nothing should be serialized. The toJSON method
34 | // will be passed the key associated with the value, and this will be
35 | // bound to the value.
36 |
37 | // For example, this would serialize Dates as ISO strings.
38 |
39 | // Date.prototype.toJSON = function (key) {
40 | // function f(n) {
41 | // // Format integers to have at least two digits.
42 | // return (n < 10)
43 | // ? "0" + n
44 | // : n;
45 | // }
46 | // return this.getUTCFullYear() + "-" +
47 | // f(this.getUTCMonth() + 1) + "-" +
48 | // f(this.getUTCDate()) + "T" +
49 | // f(this.getUTCHours()) + ":" +
50 | // f(this.getUTCMinutes()) + ":" +
51 | // f(this.getUTCSeconds()) + "Z";
52 | // };
53 |
54 | // You can provide an optional replacer method. It will be passed the
55 | // key and value of each member, with this bound to the containing
56 | // object. The value that is returned from your method will be
57 | // serialized. If your method returns undefined, then the member will
58 | // be excluded from the serialization.
59 |
60 | // If the replacer parameter is an array of strings, then it will be
61 | // used to select the members to be serialized. It filters the results
62 | // such that only members with keys listed in the replacer array are
63 | // stringified.
64 |
65 | // Values that do not have JSON representations, such as undefined or
66 | // functions, will not be serialized. Such values in objects will be
67 | // dropped; in arrays they will be replaced with null. You can use
68 | // a replacer function to replace those with JSON values.
69 |
70 | // JSON.stringify(undefined) returns undefined.
71 |
72 | // The optional space parameter produces a stringification of the
73 | // value that is filled with line breaks and indentation to make it
74 | // easier to read.
75 |
76 | // If the space parameter is a non-empty string, then that string will
77 | // be used for indentation. If the space parameter is a number, then
78 | // the indentation will be that many spaces.
79 |
80 | // Example:
81 |
82 | // text = JSON.stringify(["e", {pluribus: "unum"}]);
83 | // // text is '["e",{"pluribus":"unum"}]'
84 |
85 | // text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
86 | // // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
87 |
88 | // text = JSON.stringify([new Date()], function (key, value) {
89 | // return this[key] instanceof Date
90 | // ? "Date(" + this[key] + ")"
91 | // : value;
92 | // });
93 | // // text is '["Date(---current time---)"]'
94 |
95 | // JSON.parse(text, reviver)
96 | // This method parses a JSON text to produce an object or array.
97 | // It can throw a SyntaxError exception.
98 |
99 | // The optional reviver parameter is a function that can filter and
100 | // transform the results. It receives each of the keys and values,
101 | // and its return value is used instead of the original value.
102 | // If it returns what it received, then the structure is not modified.
103 | // If it returns undefined then the member is deleted.
104 |
105 | // Example:
106 |
107 | // // Parse the text. Values that look like ISO date strings will
108 | // // be converted to Date objects.
109 |
110 | // myData = JSON.parse(text, function (key, value) {
111 | // var a;
112 | // if (typeof value === "string") {
113 | // a =
114 | // /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
115 | // if (a) {
116 | // return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
117 | // +a[5], +a[6]));
118 | // }
119 | // }
120 | // return value;
121 | // });
122 |
123 | // myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
124 | // var d;
125 | // if (typeof value === "string" &&
126 | // value.slice(0, 5) === "Date(" &&
127 | // value.slice(-1) === ")") {
128 | // d = new Date(value.slice(5, -1));
129 | // if (d) {
130 | // return d;
131 | // }
132 | // }
133 | // return value;
134 | // });
135 |
136 | // This is a reference implementation. You are free to copy, modify, or
137 | // redistribute.
138 |
139 | /*jslint
140 | eval, for, this
141 | */
142 |
143 | /*property
144 | JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
145 | getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
146 | lastIndex, length, parse, prototype, push, replace, slice, stringify,
147 | test, toJSON, toString, valueOf
148 | */
149 |
150 |
151 | // Create a JSON object only if one does not already exist. We create the
152 | // methods in a closure to avoid creating global variables.
153 |
154 | if (typeof JSON !== "object") {
155 | JSON = {};
156 | }
157 |
158 | (function () {
159 | "use strict";
160 |
161 | var rx_one = /^[\],:{}\s]*$/;
162 | var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
163 | var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
164 | var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
165 | var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
166 | var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
167 |
168 | function f(n) {
169 | // Format integers to have at least two digits.
170 | return n < 10
171 | ? "0" + n
172 | : n;
173 | }
174 |
175 | function this_value() {
176 | return this.valueOf();
177 | }
178 |
179 | if (typeof Date.prototype.toJSON !== "function") {
180 |
181 | Date.prototype.toJSON = function () {
182 |
183 | return isFinite(this.valueOf())
184 | ? this.getUTCFullYear() + "-" +
185 | f(this.getUTCMonth() + 1) + "-" +
186 | f(this.getUTCDate()) + "T" +
187 | f(this.getUTCHours()) + ":" +
188 | f(this.getUTCMinutes()) + ":" +
189 | f(this.getUTCSeconds()) + "Z"
190 | : null;
191 | };
192 |
193 | Boolean.prototype.toJSON = this_value;
194 | Number.prototype.toJSON = this_value;
195 | String.prototype.toJSON = this_value;
196 | }
197 |
198 | var gap;
199 | var indent;
200 | var meta;
201 | var rep;
202 |
203 |
204 | function quote(string) {
205 |
206 | // If the string contains no control characters, no quote characters, and no
207 | // backslash characters, then we can safely slap some quotes around it.
208 | // Otherwise we must also replace the offending characters with safe escape
209 | // sequences.
210 |
211 | rx_escapable.lastIndex = 0;
212 | return rx_escapable.test(string)
213 | ? "\"" + string.replace(rx_escapable, function (a) {
214 | var c = meta[a];
215 | return typeof c === "string"
216 | ? c
217 | : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
218 | }) + "\""
219 | : "\"" + string + "\"";
220 | }
221 |
222 |
223 | function str(key, holder) {
224 |
225 | // Produce a string from holder[key].
226 |
227 | var i; // The loop counter.
228 | var k; // The member key.
229 | var v; // The member value.
230 | var length;
231 | var mind = gap;
232 | var partial;
233 | var value = holder[key];
234 |
235 | // If the value has a toJSON method, call it to obtain a replacement value.
236 |
237 | if (value && typeof value === "object" &&
238 | typeof value.toJSON === "function") {
239 | value = value.toJSON(key);
240 | }
241 |
242 | // If we were called with a replacer function, then call the replacer to
243 | // obtain a replacement value.
244 |
245 | if (typeof rep === "function") {
246 | value = rep.call(holder, key, value);
247 | }
248 |
249 | // What happens next depends on the value's type.
250 |
251 | switch (typeof value) {
252 | case "string":
253 | return quote(value);
254 |
255 | case "number":
256 |
257 | // JSON numbers must be finite. Encode non-finite numbers as null.
258 |
259 | return isFinite(value)
260 | ? String(value)
261 | : "null";
262 |
263 | case "boolean":
264 | case "null":
265 |
266 | // If the value is a boolean or null, convert it to a string. Note:
267 | // typeof null does not produce "null". The case is included here in
268 | // the remote chance that this gets fixed someday.
269 |
270 | return String(value);
271 |
272 | // If the type is "object", we might be dealing with an object or an array or
273 | // null.
274 |
275 | case "object":
276 |
277 | // Due to a specification blunder in ECMAScript, typeof null is "object",
278 | // so watch out for that case.
279 |
280 | if (!value) {
281 | return "null";
282 | }
283 |
284 | // Make an array to hold the partial results of stringifying this object value.
285 |
286 | gap += indent;
287 | partial = [];
288 |
289 | // Is the value an array?
290 |
291 | if (Object.prototype.toString.apply(value) === "[object Array]") {
292 |
293 | // The value is an array. Stringify every element. Use null as a placeholder
294 | // for non-JSON values.
295 |
296 | length = value.length;
297 | for (i = 0; i < length; i += 1) {
298 | partial[i] = str(i, value) || "null";
299 | }
300 |
301 | // Join all of the elements together, separated with commas, and wrap them in
302 | // brackets.
303 |
304 | v = partial.length === 0
305 | ? "[]"
306 | : gap
307 | ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
308 | : "[" + partial.join(",") + "]";
309 | gap = mind;
310 | return v;
311 | }
312 |
313 | // If the replacer is an array, use it to select the members to be stringified.
314 |
315 | if (rep && typeof rep === "object") {
316 | length = rep.length;
317 | for (i = 0; i < length; i += 1) {
318 | if (typeof rep[i] === "string") {
319 | k = rep[i];
320 | v = str(k, value);
321 | if (v) {
322 | partial.push(quote(k) + (
323 | gap
324 | ? ": "
325 | : ":"
326 | ) + v);
327 | }
328 | }
329 | }
330 | } else {
331 |
332 | // Otherwise, iterate through all of the keys in the object.
333 |
334 | for (k in value) {
335 | if (Object.prototype.hasOwnProperty.call(value, k)) {
336 | v = str(k, value);
337 | if (v) {
338 | partial.push(quote(k) + (
339 | gap
340 | ? ": "
341 | : ":"
342 | ) + v);
343 | }
344 | }
345 | }
346 | }
347 |
348 | // Join all of the member texts together, separated with commas,
349 | // and wrap them in braces.
350 |
351 | v = partial.length === 0
352 | ? "{}"
353 | : gap
354 | ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
355 | : "{" + partial.join(",") + "}";
356 | gap = mind;
357 | return v;
358 | }
359 | }
360 |
361 | // If the JSON object does not yet have a stringify method, give it one.
362 |
363 | if (typeof JSON.stringify !== "function") {
364 | meta = { // table of character substitutions
365 | "\b": "\\b",
366 | "\t": "\\t",
367 | "\n": "\\n",
368 | "\f": "\\f",
369 | "\r": "\\r",
370 | "\"": "\\\"",
371 | "\\": "\\\\"
372 | };
373 | JSON.stringify = function (value, replacer, space) {
374 |
375 | // The stringify method takes a value and an optional replacer, and an optional
376 | // space parameter, and returns a JSON text. The replacer can be a function
377 | // that can replace values, or an array of strings that will select the keys.
378 | // A default replacer method can be provided. Use of the space parameter can
379 | // produce text that is more easily readable.
380 |
381 | var i;
382 | gap = "";
383 | indent = "";
384 |
385 | // If the space parameter is a number, make an indent string containing that
386 | // many spaces.
387 |
388 | if (typeof space === "number") {
389 | for (i = 0; i < space; i += 1) {
390 | indent += " ";
391 | }
392 |
393 | // If the space parameter is a string, it will be used as the indent string.
394 |
395 | } else if (typeof space === "string") {
396 | indent = space;
397 | }
398 |
399 | // If there is a replacer, it must be a function or an array.
400 | // Otherwise, throw an error.
401 |
402 | rep = replacer;
403 | if (replacer && typeof replacer !== "function" &&
404 | (typeof replacer !== "object" ||
405 | typeof replacer.length !== "number")) {
406 | throw new Error("JSON.stringify");
407 | }
408 |
409 | // Make a fake root object containing our value under the key of "".
410 | // Return the result of stringifying the value.
411 |
412 | return str("", {"": value});
413 | };
414 | }
415 |
416 |
417 | // If the JSON object does not yet have a parse method, give it one.
418 |
419 | if (typeof JSON.parse !== "function") {
420 | JSON.parse = function (text, reviver) {
421 |
422 | // The parse method takes a text and an optional reviver function, and returns
423 | // a JavaScript value if the text is a valid JSON text.
424 |
425 | var j;
426 |
427 | function walk(holder, key) {
428 |
429 | // The walk method is used to recursively walk the resulting structure so
430 | // that modifications can be made.
431 |
432 | var k;
433 | var v;
434 | var value = holder[key];
435 | if (value && typeof value === "object") {
436 | for (k in value) {
437 | if (Object.prototype.hasOwnProperty.call(value, k)) {
438 | v = walk(value, k);
439 | if (v !== undefined) {
440 | value[k] = v;
441 | } else {
442 | delete value[k];
443 | }
444 | }
445 | }
446 | }
447 | return reviver.call(holder, key, value);
448 | }
449 |
450 |
451 | // Parsing happens in four stages. In the first stage, we replace certain
452 | // Unicode characters with escape sequences. JavaScript handles many characters
453 | // incorrectly, either silently deleting them, or treating them as line endings.
454 |
455 | text = String(text);
456 | rx_dangerous.lastIndex = 0;
457 | if (rx_dangerous.test(text)) {
458 | text = text.replace(rx_dangerous, function (a) {
459 | return "\\u" +
460 | ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
461 | });
462 | }
463 |
464 | // In the second stage, we run the text against regular expressions that look
465 | // for non-JSON patterns. We are especially concerned with "()" and "new"
466 | // because they can cause invocation, and "=" because it can cause mutation.
467 | // But just to be safe, we want to reject all unexpected forms.
468 |
469 | // We split the second stage into 4 regexp operations in order to work around
470 | // crippling inefficiencies in IE's and Safari's regexp engines. First we
471 | // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
472 | // replace all simple value tokens with "]" characters. Third, we delete all
473 | // open brackets that follow a colon or comma or that begin the text. Finally,
474 | // we look to see that the remaining characters are only whitespace or "]" or
475 | // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
476 |
477 | if (
478 | rx_one.test(
479 | text
480 | .replace(rx_two, "@")
481 | .replace(rx_three, "]")
482 | .replace(rx_four, "")
483 | )
484 | ) {
485 |
486 | // In the third stage we use the eval function to compile the text into a
487 | // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
488 | // in JavaScript: it can begin a block or an object literal. We wrap the text
489 | // in parens to eliminate the ambiguity.
490 |
491 | j = eval("(" + text + ")");
492 |
493 | // In the optional fourth stage, we recursively walk the new structure, passing
494 | // each name/value pair to a reviver function for possible transformation.
495 |
496 | return (typeof reviver === "function")
497 | ? walk({"": j}, "")
498 | : j;
499 | }
500 |
501 | // If the text is not JSON parseable, then a SyntaxError is thrown.
502 |
503 | throw new SyntaxError("JSON.parse");
504 | };
505 | }
506 | }());
507 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/main.js:
--------------------------------------------------------------------------------
1 | var curPageUrl;
2 | var prePageUrl;
3 |
4 | function navi2page(newpage) {
5 | prePageUrl = curPageUrl;
6 | curPageUrl = newpage;
7 | $("#bodymain").load(newpage);
8 | }
9 |
10 | function back2page() {
11 | curPageUrl = prePageUrl;
12 | $("#bodymain").load(curPageUrl);
13 | }
14 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/npm.js:
--------------------------------------------------------------------------------
1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
2 | require('../../js/transition.js')
3 | require('../../js/alert.js')
4 | require('../../js/button.js')
5 | require('../../js/carousel.js')
6 | require('../../js/collapse.js')
7 | require('../../js/dropdown.js')
8 | require('../../js/modal.js')
9 | require('../../js/tooltip.js')
10 | require('../../js/popover.js')
11 | require('../../js/scrollspy.js')
12 | require('../../js/tab.js')
13 | require('../../js/affix.js')
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/product.js:
--------------------------------------------------------------------------------
1 | function oper_detail(value, row) {
2 | var href = "/detail.html?id=" + row.id;
3 | return "商品详情 ";
4 | }
5 |
6 | function oper_cart(value, row) {
7 | var json = {
8 | productId: row.id,
9 | productName: row.name,
10 | productPrice: row.price,
11 | count: 1
12 | };
13 | return "加入购物车 ";
14 | }
15 |
16 | function addToCart(row) {
17 | var reqUrl = "/cart/add-cart";
18 | $.ajax({
19 | type: 'POST',
20 | url: reqUrl,
21 | data: JSON.stringify(row),
22 | dataType: 'json',
23 | contentType: "application/json ; charset=utf-8",
24 | success: function (data) {
25 | var code = data.code;
26 | if (code != undefined) {
27 | if (code == 200) {
28 | navi2page("/cart.html");
29 | } else if (code == 503) {
30 | navi2page("/login.html");
31 | } else {
32 | alert("add to cart error");
33 | }
34 | return;
35 | }
36 | var directUrl = data.redirect;
37 | if (directUrl != undefined) {
38 | navi2page(directUrl);
39 | return;
40 | }
41 | }
42 | });
43 | };
44 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/js/urlparam.js:
--------------------------------------------------------------------------------
1 | function getQueryString(url, paramName) {
2 | var result = "";
3 | if (!url.length) return result;
4 | var parts = url.split(/\?|\&/);
5 | for (var i = 0, len = parts.length; i < len; i++) {
6 | var tokens = parts[i].split("=");
7 | if (tokens[0] == paramName) {
8 | return decodeURIComponent(tokens[1]);
9 | }
10 | }
11 | return result;
12 | }
13 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | My Shop Plantform
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | My Shop Plantform
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/eshop-web/src/main/resources/static/product.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | My Shop Plantform
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
19 |
20 |
21 | ID
22 | 商品名称
23 | 商品价格
24 | 商品描述
25 | 加入购物车
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/eureka-server/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | Springcloud_eShop
6 | Springcloud_eShop
7 | 0.0.1-SNAPSHOT
8 |
9 | sc_eureka-server
10 | sc_eureka-server
11 | jar
12 |
13 |
14 | org.springframework.cloud
15 | spring-cloud-starter-eureka-server
16 | ${spring.cloud.version}
17 |
18 |
19 |
20 |
21 | eshop_eureka-server
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-maven-plugin
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/eureka-server/src/main/java/com/mycat/monoeshop/App.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
6 |
7 | /**
8 | * Desc:
9 | *
10 | * @date: 27/08/2017
11 | * @author: Leader us
12 | */
13 | @SpringBootApplication
14 | @EnableEurekaServer
15 | public class App {
16 |
17 | public static void main(String[] args) {
18 | SpringApplication.run(App.class, args);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/eureka-server/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: micro-eureka-server
4 | info:
5 | app:
6 | name: ${spring.application.name}
7 | version: v1.0.0
8 | logging:
9 | config: classpath:logback.xml
10 | server:
11 | port: 8030
12 | context-path: /
13 | tomcat:
14 | uri-encoding: UTF-8
15 | eureka:
16 | instance:
17 | hostname: 127.0.0.1
18 | prefer-ip-address: true
19 | client:
20 | registerWithEureka: false
21 | fetchRegistry: false
22 | service-url:
23 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
--------------------------------------------------------------------------------
/eureka-server/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | Springcloud_eShop
5 | Springcloud_eShop
6 | 0.0.1-SNAPSHOT
7 | pom
8 |
9 | org.springframework.boot
10 | spring-boot-starter-parent
11 | 1.5.3.RELEASE
12 |
13 |
14 |
15 | UTF-8
16 | UTF-8
17 | UTF-8
18 | 1.8
19 | 1.1.1
20 | 1.0.29
21 | 2.4
22 | 1.3.4.RELEASE
23 |
24 |
25 |
26 | eureka-server
27 | zuul-gateway
28 | cart-service
29 | auth-service
30 | product-service
31 | eshop-web
32 |
33 |
34 |
35 |
36 | org.springframework.cloud
37 | spring-cloud-starter-eureka
38 | ${spring.cloud.version}
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-actuator
43 |
44 |
45 | commons-io
46 | commons-io
47 | ${commons.io.version}
48 |
49 |
50 |
51 | ch.qos.logback
52 | logback-classic
53 |
54 |
55 |
57 |
58 |
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-maven-plugin
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/product-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | Springcloud_eShop
6 | Springcloud_eShop
7 | 0.0.1-SNAPSHOT
8 |
9 | sc_product-service
10 | sc_product-service
11 | jar
12 |
13 | UTF-8
14 | UTF-8
15 | UTF-8
16 | 1.8
17 | 1.1.1
18 | 1.0.29
19 | 2.4
20 |
21 |
22 |
23 | com.alibaba
24 | druid
25 | ${druid.version}
26 |
27 |
28 | org.mybatis.spring.boot
29 | mybatis-spring-boot-starter
30 | ${mybatis.version}
31 |
32 |
33 | mysql
34 | mysql-connector-java
35 |
36 |
37 |
38 |
39 | eshop_sc_product-service
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-maven-plugin
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/product-service/src/main/java/com/mycat/monoeshop/App.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7 |
8 | /**
9 | * Desc:
10 | *
11 | * @date: 27/08/2017
12 | * @author: Leader us
13 | */
14 | @SpringBootApplication
15 | @MapperScan("com.mycat.monoeshop.mapper")
16 | @EnableDiscoveryClient
17 | public class App {
18 |
19 | public static void main(String[] args) {
20 | SpringApplication.run(App.class, args);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/product-service/src/main/java/com/mycat/monoeshop/config/MyAppConfig.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.config;
2 |
3 | import javax.sql.DataSource;
4 |
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.cache.annotation.CachingConfigurerSupport;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | import com.alibaba.druid.pool.DruidDataSource;
11 |
12 | /**
13 | * Desc:
14 | *
15 | * @date: 27/08/2017
16 | * @author: Leader us
17 | */
18 | @Configuration
19 | public class MyAppConfig extends CachingConfigurerSupport {
20 |
21 | @Configuration
22 | public class DruidDataSourceConfig {
23 | @Bean
24 | @ConfigurationProperties(prefix = "spring.datasource")
25 | public DataSource druidDataSource() {
26 | DruidDataSource druidDataSource = new DruidDataSource();
27 | return druidDataSource;
28 | }
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/product-service/src/main/java/com/mycat/monoeshop/mapper/ProductMapper.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.mapper;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.ibatis.annotations.Select;
6 |
7 | import com.mycat.monoeshop.model.Product;
8 |
9 | /**
10 | * Desc:
11 | *
12 | * @date: 27/08/2017
13 | * @author: Leader us
14 | */
15 | public interface ProductMapper {
16 | @Select("select * from product")
17 | List getProducts();
18 |
19 | @Select("select * from product where id=#{id,jdbcType=INTEGER}")
20 | Product getProductById(Integer id);
21 | }
22 |
--------------------------------------------------------------------------------
/product-service/src/main/java/com/mycat/monoeshop/model/Product.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | import java.math.BigDecimal;
4 |
5 | /**
6 | * Desc:
7 | *
8 | * @date: 27/08/2017
9 | * @author: Leader us
10 | */
11 | public class Product {
12 | private Integer id;
13 | private String name;
14 | private BigDecimal price;
15 | private String desc;
16 |
17 | public Integer getId() {
18 | return id;
19 | }
20 |
21 | public void setId(Integer id) {
22 | this.id = id;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 |
33 | public BigDecimal getPrice() {
34 | return price;
35 | }
36 |
37 | public void setPrice(BigDecimal price) {
38 | this.price = price;
39 | }
40 |
41 | public String getDesc() {
42 | return desc;
43 | }
44 |
45 | public void setDesc(String desc) {
46 | this.desc = desc;
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "Product{" +
52 | "id=" + id +
53 | ", name='" + name + '\'' +
54 | ", price=" + price +
55 | ", desc='" + desc + '\'' +
56 | '}';
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/product-service/src/main/java/com/mycat/monoeshop/rest/ProductRestService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.rest;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.web.bind.annotation.PathVariable;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.ResponseBody;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | import com.mycat.monoeshop.model.Product;
12 | import com.mycat.monoeshop.service.ProductService;
13 |
14 | /**
15 | * Desc:
16 | *
17 | * @date: 27/08/2017
18 | * @author: Leader us
19 | */
20 | @RestController
21 | @RequestMapping("/products")
22 | public class ProductRestService {
23 | @Autowired
24 | private ProductService productService;
25 |
26 | @RequestMapping("/all")
27 | @ResponseBody
28 | public List getProducts() {
29 | return productService.getProducts();
30 | }
31 |
32 | @RequestMapping("/{id}")
33 | @ResponseBody
34 | public Product getProductById(@PathVariable Integer id) {
35 | return productService.getProductById(id);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/product-service/src/main/java/com/mycat/monoeshop/service/ProductService.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.service;
2 |
3 | import java.util.List;
4 |
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | import com.mycat.monoeshop.mapper.ProductMapper;
11 | import com.mycat.monoeshop.model.Product;
12 |
13 | /**
14 | * Desc:
15 | *
16 | * @date: 27/08/2017
17 | * @author: Leader us
18 | */
19 | @Service
20 | public class ProductService {
21 | private static final Logger LOGGER = LoggerFactory.getLogger(ProductService.class);
22 |
23 | @Autowired
24 | private ProductMapper productMapper;
25 |
26 | public List getProducts() {
27 | LOGGER.info("request for all products");
28 | List products = productMapper.getProducts();
29 | LOGGER.info("product size: {}", products == null ? 0 : products.size());
30 | return products;
31 | }
32 |
33 | public Product getProductById(Integer id) {
34 |
35 | Product result=productMapper.getProductById(id);
36 | LOGGER.info("request for productId: {},founded {}", id,result!=null);
37 | return result;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/product-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: eshop-product-service
4 | datasource:
5 | type: com.alibaba.druid.pool.DruidDataSource
6 | url: jdbc:mysql://192.168.18.134:3306/HPE_APP?useSSL=false
7 | username: lession
8 | password: mypass
9 | driver-class-name: com.mysql.jdbc.Driver
10 | initialSize: 2
11 | minIdle: 2
12 | maxActive: 20
13 | maxWait: 60000
14 | timeBetweenEvictionRunsMillis: 60000
15 | minEvictableIdleTimeMillis: 300000
16 | validationQuery: SELECT 1 FROM DUAL
17 | testWhileIdle: true
18 | testOnBorrow: true
19 | testOnReturn: false
20 | poolPreparedStatements: true
21 | maxPoolPreparedStatementPerConnectionSize: 20
22 | schema: classpath:create-db.sql
23 | data: classpath:demo-data.sql
24 | initialize: true
25 | continueOnError: true
26 | info:
27 | app:
28 | name: ${spring.application.name}
29 | version: v1.0.0
30 | server:
31 | port: 8036
32 | context-path: /
33 | tomcat:
34 | uri-encoding: UTF-8
35 |
36 | logging:
37 | config: classpath:logback.xml
38 | eureka:
39 | instance:
40 | hostname: 127.0.0.1
41 | prefer-ip-address: true
42 | client:
43 | healthcheck:
44 | enabled: true
45 | registerWithEureka: true
46 | fetchRegistry: true
47 | service-url:
48 | defaultZone: http://127.0.0.1:8030/eureka/
49 |
50 |
--------------------------------------------------------------------------------
/product-service/src/main/resources/create-db.sql:
--------------------------------------------------------------------------------
1 | --创建product表
2 | CREATE TABLE IF NOT EXISTS `product`(
3 | `id` INT,
4 | `name` VARCHAR(20),
5 | `price` DECIMAL(10,2),
6 | `desc` VARCHAR(20),
7 | PRIMARY KEY ( `id` )
8 | )ENGINE=InnoDB DEFAULT CHARSET=utf8;
--------------------------------------------------------------------------------
/product-service/src/main/resources/demo-data.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO product VALUES (1,'Apple',5,'Real apple');
2 | INSERT INTO product VALUES (2,'Car',10000,'Good car');
3 | INSERT INTO product VALUES (3,'House',20000,'Big House');
--------------------------------------------------------------------------------
/product-service/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/zuul-gateway/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | Springcloud_eShop
6 | Springcloud_eShop
7 | 0.0.1-SNAPSHOT
8 |
9 | sc_zuul-gateway
10 | sc_zuul-gateway
11 | jar
12 |
13 |
14 | org.springframework.boot
15 | spring-boot-starter-web
16 |
17 |
18 | org.springframework.boot
19 | spring-boot-starter-data-redis
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-starter-logging
24 |
25 |
26 |
27 |
28 | org.springframework.session
29 | spring-session-data-redis
30 |
31 |
32 | org.springframework.cloud
33 | spring-cloud-starter-zuul
34 | ${spring.cloud.version}
35 |
36 |
37 | com.fasterxml.jackson.core
38 | jackson-core
39 |
40 |
41 | com.fasterxml.jackson.core
42 | jackson-annotations
43 |
44 |
45 | com.fasterxml.jackson.core
46 | jackson-databind
47 |
48 |
49 |
50 |
51 |
52 | eshop_zuul-gateway
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-maven-plugin
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/App.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
6 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
7 |
8 | /**
9 | * Desc:
10 | *
11 | * @date: 27/08/2017
12 | * @author: Leader us
13 | */
14 | @SpringBootApplication
15 | @EnableRedisHttpSession
16 | @EnableZuulProxy
17 | public class App {
18 | /**
19 | * 记录用户Session是否登录过
20 | */
21 | public final static String SESSION_KEY = "user_sid";
22 |
23 | public static void main(String[] args) {
24 | SpringApplication.run(App.class, args);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/config/FilterConfig.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 |
6 | import com.mycat.monoeshop.filter.LoginPostFilter;
7 | import com.mycat.monoeshop.filter.SecurityPreFilter;
8 | import com.netflix.zuul.ZuulFilter;
9 |
10 | /**
11 | * Desc:
12 | *
13 | * @date: 02/07/2017
14 | * @author: gaozhiwen
15 | */
16 | @Configuration
17 | public class FilterConfig {
18 | @Bean
19 | public ZuulFilter securityPreFilter() {
20 | return new SecurityPreFilter();
21 | }
22 |
23 | @Bean
24 | public ZuulFilter loginPostFilter() {
25 | return new LoginPostFilter();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/config/MyAppConfig.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.config;
2 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
3 | import com.fasterxml.jackson.annotation.PropertyAccessor;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 |
6 | import javax.sql.DataSource;
7 |
8 | import org.springframework.boot.context.properties.ConfigurationProperties;
9 | import org.springframework.cache.CacheManager;
10 | import org.springframework.cache.annotation.CachingConfigurerSupport;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 | import org.springframework.data.redis.cache.RedisCacheManager;
14 | import org.springframework.data.redis.connection.RedisConnectionFactory;
15 | import org.springframework.data.redis.core.RedisTemplate;
16 | import org.springframework.data.redis.core.StringRedisTemplate;
17 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
18 | import org.springframework.data.redis.serializer.RedisSerializer;
19 | import org.springframework.data.redis.serializer.StringRedisSerializer;
20 |
21 | /**
22 | * Desc:
23 | *
24 | * @date: 27/08/2017
25 | * @author: Leader us
26 | */
27 | @Configuration
28 | public class MyAppConfig extends CachingConfigurerSupport {
29 |
30 | @Bean
31 | public CacheManager cacheManager(RedisTemplate redisTemplate) {
32 | RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
33 | // 设置缓存过期时间
34 | // rcm.setDefaultExpiration(60);//秒
35 | return rcm;
36 |
37 | }
38 |
39 | /**
40 | * RedisTemplate配置
41 | */
42 | @Bean
43 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
44 | StringRedisTemplate template = new StringRedisTemplate(factory);
45 | // 定义key序列化方式
46 | RedisSerializer redisSerializer = new StringRedisSerializer();// Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
47 | // 定义value的序列化方式
48 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
49 | ObjectMapper om = new ObjectMapper();
50 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
51 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
52 | jackson2JsonRedisSerializer.setObjectMapper(om);
53 |
54 | template.setKeySerializer(jackson2JsonRedisSerializer);
55 | template.setValueSerializer(jackson2JsonRedisSerializer);
56 | template.setHashKeySerializer(jackson2JsonRedisSerializer);
57 | template.setHashValueSerializer(jackson2JsonRedisSerializer);
58 | template.afterPropertiesSet();
59 | return template;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/controller/SessionController.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.controller;
2 |
3 | import org.apache.commons.lang.StringUtils;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.web.bind.annotation.GetMapping;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | import com.mycat.monoeshop.App;
10 | import com.mycat.monoeshop.model.Result;
11 | import com.mycat.monoeshop.model.ResultEnum;
12 |
13 | import java.util.Arrays;
14 | import java.util.stream.Stream;
15 |
16 | import javax.servlet.http.HttpServletRequest;
17 |
18 | /**
19 | * Desc:
20 | *
21 | * @date: 27/08/2017
22 | * @author: Leader us
23 | */
24 | @RestController
25 | public class SessionController {
26 | private static final Logger LOGGER = LoggerFactory.getLogger(SessionController.class);
27 |
28 | @GetMapping("/session/token")
29 | public Result checkToken(HttpServletRequest request) {
30 | Result result = null;
31 | LOGGER.info("session cookied: {}",Arrays.toString(request.getCookies()));
32 | Stream.of(request.getCookies()).forEach(a -> {System.out.println("xxx cookie "+a.getName()+" "+a.getValue());});
33 | String sessionToken = (String) request.getSession().getAttribute(App.SESSION_KEY);
34 |
35 | if (StringUtils.isEmpty(sessionToken)) {
36 | LOGGER.warn("no session key found ,shoud login ");
37 | result = new Result(ResultEnum.NOT_LOGIN);
38 | } else {
39 | LOGGER.info(" session key found ,ok , session id "+request.getSession().getId()+" "+sessionToken);
40 | result = new Result(ResultEnum.SUCCESS);
41 | }
42 | return result;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/filter/JacksonUtil.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.filter;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.core.JsonParser;
5 | import com.fasterxml.jackson.core.Version;
6 | import com.fasterxml.jackson.databind.DeserializationFeature;
7 | import com.fasterxml.jackson.databind.JavaType;
8 | import com.fasterxml.jackson.databind.ObjectMapper;
9 | import com.fasterxml.jackson.databind.SerializationFeature;
10 | import com.fasterxml.jackson.databind.module.SimpleModule;
11 | import org.apache.commons.lang.StringUtils;
12 |
13 | import java.util.List;
14 |
15 | public class JacksonUtil {
16 | private final static ObjectMapper objectMapper = new ObjectMapper();
17 |
18 | static {
19 | SimpleModule simpleModule = new SimpleModule("SimpleJodaModule", new Version(1, 0, 0, null, null, null));
20 | objectMapper.registerModule(simpleModule);
21 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
22 | objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
23 | objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
24 | objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
25 | objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
26 | objectMapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);
27 | objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
28 | objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
29 | }
30 |
31 | public static String encode(Object obj) {
32 | try {
33 | return objectMapper.writeValueAsString(obj);
34 | } catch (Exception ignored) {
35 | }
36 | return null;
37 | }
38 |
39 | /**
40 | * 将json string反序列化成对象
41 | *
42 | * @param json
43 | * @param valueType
44 | * @return
45 | */
46 | public static T decode(String json, Class valueType) {
47 | if (StringUtils.isEmpty(json)) {
48 | return null;
49 | }
50 | try {
51 | return objectMapper.readValue(json, valueType);
52 | } catch (Exception ignored) {
53 | }
54 | return null;
55 | }
56 |
57 | public static List decodeList(String json, Class valueType) {
58 | try {
59 | JavaType javaType = getCollectionType(List.class, valueType);
60 | return (List) objectMapper.readValue(json, javaType);
61 | } catch (Exception ignored) {
62 | }
63 | return null;
64 | }
65 |
66 | private static JavaType getCollectionType(Class> collectionClass, Class>... elementClasses) {
67 | return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/filter/LoginPostFilter.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.filter;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | import javax.servlet.http.HttpSession;
7 |
8 | import org.apache.commons.io.IOUtils;
9 | import org.apache.commons.lang.StringUtils;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
13 |
14 | import com.google.common.base.Charsets;
15 | import com.mycat.monoeshop.App;
16 | import com.netflix.zuul.ZuulFilter;
17 | import com.netflix.zuul.context.RequestContext;
18 |
19 | /**
20 | * Desc:
21 | *
22 | * @date: 27/08/2017
23 | * @author: Leader us
24 | */
25 | public class LoginPostFilter extends ZuulFilter {
26 | private static final Logger LOGGER = LoggerFactory.getLogger(LoginPostFilter.class);
27 |
28 | @Override
29 | public String filterType() {
30 | return FilterConstants.POST_TYPE;
31 | }
32 |
33 | @Override
34 | public int filterOrder() {
35 | return 10;
36 | }
37 |
38 | @Override
39 | public boolean shouldFilter() {
40 | RequestContext context = RequestContext.getCurrentContext();
41 | String uri = context.getRequest().getRequestURI();
42 | if (uri.startsWith("/account/login")) {
43 | LOGGER.info("filter login url "+uri.toString());
44 | return true;
45 | }
46 | return false;
47 | }
48 |
49 | @Override
50 | public Object run() {
51 | LOGGER.info("security post filter");
52 |
53 | RequestContext context = RequestContext.getCurrentContext();
54 | String result = null;
55 |
56 | if (context.getResponseBody() != null) {
57 | result = context.getResponseBody();
58 | context.setResponseBody(wrapResult(context, result));
59 | } else if (context.getResponseDataStream() != null) {
60 | InputStream is = context.getResponseDataStream();
61 | try {
62 | result = IOUtils.toString(is, Charsets.UTF_8.name());
63 | String tokenId = wrapResult(context, result);
64 | if (StringUtils.isNotEmpty(tokenId)) {
65 | context.setResponseDataStream(IOUtils.toInputStream(tokenId));
66 | }
67 | } catch (IOException e) {
68 | LOGGER.error("error to handle response "+e);
69 | }
70 | }
71 |
72 | return null;
73 | }
74 |
75 | private String wrapResult(RequestContext context, String result) {
76 | String tokenId = null;
77 | if (StringUtils.isNotEmpty(result)) {
78 | HttpSession session = context.getRequest().getSession();
79 | tokenId = session.getId();
80 | session.setAttribute(App.SESSION_KEY, result);
81 | session.setMaxInactiveInterval(60 * 60 * 12);
82 | LOGGER.info("login post filter result: {}, tokenId: {}", result, tokenId);
83 | }
84 | return tokenId;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/filter/SecurityPreFilter.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.filter;
2 |
3 | import java.util.stream.Stream;
4 |
5 | import javax.servlet.http.HttpSession;
6 |
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
10 |
11 | import com.mycat.monoeshop.App;
12 | import com.mycat.monoeshop.model.Account;
13 | import com.mycat.monoeshop.model.Result;
14 | import com.mycat.monoeshop.model.ResultEnum;
15 | import com.netflix.zuul.ZuulFilter;
16 | import com.netflix.zuul.context.RequestContext;
17 |
18 | /**
19 | * Desc:
20 | *
21 | * @date: 27/08/2017
22 | * @author: Leader us
23 | */
24 | public class SecurityPreFilter extends ZuulFilter {
25 | private static final Logger LOGGER = LoggerFactory.getLogger(SecurityPreFilter.class);
26 |
27 | @Override
28 | public String filterType() {
29 | return FilterConstants.PRE_TYPE;
30 | }
31 |
32 | @Override
33 | public int filterOrder() {
34 | return -100;
35 | }
36 |
37 | @Override
38 | public boolean shouldFilter() {
39 | String uri = getContext().getRequest().getRequestURI();
40 | return uri.startsWith("/cart/");
41 | }
42 |
43 | @Override
44 | public Object run() {
45 | LOGGER.info("security pre filter");
46 |
47 | HttpSession session = getContext().getRequest().getSession();
48 | Stream.of(getContext().getRequest().getCookies()).forEach(a -> {System.out.println("yyy cookie "+a.getName()+" "+a.getValue());});
49 | String accountStr = (String) session.getAttribute(App.SESSION_KEY);
50 | Account account = JacksonUtil.decode(accountStr, Account.class);
51 | LOGGER.info("sessionid "+session.getId()+" account: {}", account);
52 | if (account != null) {
53 | getContext().addZuulRequestHeader("accountName", account.getName());
54 |
55 | } else {
56 | LOGGER.warn("account no login, send response directly");
57 | getContext().setSendZuulResponse(true);
58 | getContext().setResponseStatusCode(400);
59 | getContext().setResponseBody(JacksonUtil.encode(new Result(ResultEnum.NOT_LOGIN)));
60 | }
61 | LOGGER.info("session id: {}", session.getId());
62 | return null;
63 | }
64 |
65 | private RequestContext getContext() {
66 | return RequestContext.getCurrentContext();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/model/Account.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public class Account {
10 | private String name;
11 | private String password;
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | public void setName(String name) {
18 | this.name = name;
19 | }
20 |
21 | public String getPassword() {
22 | return password;
23 | }
24 |
25 | public void setPassword(String password) {
26 | this.password = password;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/model/Result.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public class Result {
10 | private int code;
11 | private String desc;
12 | private T data;
13 |
14 | public Result()
15 | {
16 |
17 | }
18 | public Result(ResultEnum resultEnum) {
19 | this.code = resultEnum.getCode();
20 | this.desc = resultEnum.getDesc();
21 | }
22 |
23 | public Result(ResultEnum resultEnum, T data) {
24 | this.code = resultEnum.getCode();
25 | this.desc = resultEnum.getDesc();
26 | this.data = data;
27 | }
28 |
29 | public int getCode() {
30 | return code;
31 | }
32 |
33 | public void setCode(int code) {
34 | this.code = code;
35 | }
36 |
37 | public String getDesc() {
38 | return desc;
39 | }
40 |
41 | public void setDesc(String desc) {
42 | this.desc = desc;
43 | }
44 |
45 | public T getData() {
46 | return data;
47 | }
48 |
49 | public void setData(T data) {
50 | this.data = data;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/mycat/monoeshop/model/ResultEnum.java:
--------------------------------------------------------------------------------
1 | package com.mycat.monoeshop.model;
2 |
3 | /**
4 | * Desc:
5 | *
6 | * @date: 27/08/2017
7 | * @author: Leader us
8 | */
9 | public enum ResultEnum {
10 | SUCCESS(200, "success"), ERROR(502, "error"), NOT_LOGIN(503, "not login");
11 |
12 | private int code;
13 | private String desc;
14 |
15 | ResultEnum(int code, String desc) {
16 | this.code = code;
17 | this.desc = desc;
18 | }
19 |
20 | public int getCode() {
21 | return code;
22 | }
23 |
24 | public String getDesc() {
25 | return desc;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: micro-gateway
4 | redis:
5 | host: 192.168.18.134
6 | port: 6379
7 | #password:
8 | info:
9 | app:
10 | name: ${spring.application.name}
11 | version: v1.0.0
12 | server:
13 | port: 8031
14 | context-path: /
15 | tomcat:
16 | uri-encoding: UTF-8
17 |
18 | logging:
19 | config: classpath:logback.xml
20 | eureka:
21 | instance:
22 | hostname: 127.0.0.1
23 | prefer-ip-address: true
24 | client:
25 | healthcheck:
26 | enabled: true
27 | registerWithEureka: true
28 | fetchRegistry: true
29 | service-url:
30 | defaultZone: http://127.0.0.1:8030/eureka/
31 |
32 | zuul:
33 | ribbon-isolation-strategy: THREAD # SEMAPHORE THREAD
34 | sensitive-headers:
35 | ignored-headers:
36 | ignored-services: '*'
37 | retryable: true
38 | routes:
39 | session:
40 | path: /session/**
41 | url: forward:/session
42 | account:
43 | path: /account/**
44 | serviceId: eshop-auth-service
45 | stripPrefix: false
46 | product:
47 | path: /products/**
48 | serviceId: eshop-product-service
49 | stripPrefix: false
50 | cart:
51 | path: /cart/**
52 | serviceId: eshop-cart-service
53 | stripPrefix: false
54 |
55 | hystrix:
56 | command:
57 | default:
58 | execution:
59 | isolation:
60 | thread:
61 | timeoutInMilliseconds: 10000
62 |
63 | ribbon:
64 | MaxAutoRetries: 2
65 | MaxAutoRetriesNextServer: 3
66 | restclient:
67 | enabled: true
--------------------------------------------------------------------------------
/zuul-gateway/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------