sunlightcs 7 years ago
parent
commit
afd9e2074e
52 changed files with 770 additions and 498 deletions
  1. 1 1
      Dockerfile
  2. 1 8
      doc/db.sql
  3. 7 1
      pom-war.xml
  4. 13 0
      pom.xml
  5. 88 0
      src/main/java/io/renren/common/utils/JwtUtils.java
  6. 1 0
      src/main/java/io/renren/common/utils/R.java
  7. 10 0
      src/main/java/io/renren/common/utils/ShiroUtils.java
  8. 32 0
      src/main/java/io/renren/config/KaptchaConfig.java
  9. 3 2
      src/main/java/io/renren/config/ShiroConfig.java
  10. 14 0
      src/main/java/io/renren/datasources/DataSourceNames.java
  11. 28 0
      src/main/java/io/renren/datasources/DataSourceTestService.java
  12. 1 1
      src/main/java/io/renren/dynamicdatasource/DynamicDataSource.java
  13. 3 3
      src/main/java/io/renren/dynamicdatasource/DynamicDataSourceConfig.java
  14. 16 0
      src/main/java/io/renren/datasources/annotation/DataSource.java
  15. 60 0
      src/main/java/io/renren/datasources/aspect/DataSourceAspect.java
  16. 0 23
      src/main/java/io/renren/dynamicdatasource/DataSourceContext.java
  17. 0 46
      src/main/java/io/renren/modules/api/controller/ApiTestController.java
  18. 0 21
      src/main/java/io/renren/modules/api/dao/TokenDao.java
  19. 0 75
      src/main/java/io/renren/modules/api/entity/TokenEntity.java
  20. 0 32
      src/main/java/io/renren/modules/api/service/TokenService.java
  21. 0 80
      src/main/java/io/renren/modules/api/service/impl/TokenServiceImpl.java
  22. 4 5
      src/main/java/io/renren/modules/api/annotation/AuthIgnore.java
  23. 1 1
      src/main/java/io/renren/modules/api/annotation/LoginUser.java
  24. 4 4
      src/main/java/io/renren/modules/api/config/WebMvcConfig.java
  25. 12 9
      src/main/java/io/renren/modules/api/controller/ApiLoginController.java
  26. 3 5
      src/main/java/io/renren/modules/api/controller/ApiRegisterController.java
  27. 50 0
      src/main/java/io/renren/modules/app/controller/ApiTestController.java
  28. 2 2
      src/main/java/io/renren/modules/api/dao/UserDao.java
  29. 1 1
      src/main/java/io/renren/modules/api/entity/UserEntity.java
  30. 19 21
      src/main/java/io/renren/modules/api/interceptor/AuthorizationInterceptor.java
  31. 6 6
      src/main/java/io/renren/modules/api/resolver/LoginUserHandlerMethodArgumentResolver.java
  32. 2 2
      src/main/java/io/renren/modules/api/service/UserService.java
  33. 4 4
      src/main/java/io/renren/modules/api/service/impl/UserServiceImpl.java
  34. 1 1
      src/main/java/io/renren/modules/job/utils/ScheduleUtils.java
  35. 5 5
      src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java
  36. 9 6
      src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java
  37. 20 20
      src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java
  38. 5 5
      src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java
  39. 7 7
      src/main/java/io/renren/modules/oss/controller/SysOssController.java
  40. 40 1
      src/main/java/io/renren/modules/sys/controller/SysLoginController.java
  41. 0 4
      src/main/java/io/renren/modules/sys/controller/SysMenuController.java
  42. 2 2
      src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java
  43. 1 1
      src/main/resources/application-dev.yml
  44. 10 1
      src/main/resources/application.yml
  45. 0 41
      src/main/resources/mapper/api/TokenDao.xml
  46. 4 4
      src/main/resources/mapper/api/UserDao.xml
  47. 1 1
      src/main/resources/static/js/modules/sys/menu.js
  48. 1 1
      src/main/resources/static/js/modules/sys/role.js
  49. 191 0
      src/main/resources/static/libs/store.js
  50. 50 36
      src/main/resources/views/login.html
  51. 13 9
      src/test/java/io/renren/DynamicDataSourceTest.java
  52. 24 0
      src/test/java/io/renren/JwtTest.java

+ 1 - 1
Dockerfile

@ -2,6 +2,6 @@ FROM java:8
2 2
EXPOSE 8080
3 3
4 4
VOLUME /tmp
5
ADD renren-fast-1.2.0.jar /app.jar
5
ADD renren-fast.jar /app.jar
6 6
RUN bash -c 'touch /app.jar'
7 7
ENTRYPOINT ["java","-jar","/app.jar"]

+ 1 - 8
doc/db.sql

@ -128,7 +128,7 @@ INSERT INTO `sys_menu` (`menu_id`, `parent_id`, `name`, `url`, `perms`, `type`,
128 128
129 129
130 130
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
131
-- APP接口相关SQL,如果不使用该功能,则不用执行下面SQL -------------------------------------------------------------------------------------------------------------
131 132
-- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
132 133
133 134
-- 用户表
@ -142,15 +142,6 @@ CREATE TABLE `tb_user` (
142 142
  UNIQUE INDEX (`username`)
143 143
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户';
144 144
145
CREATE TABLE `tb_token` (
146
  `user_id` bigint NOT NULL,
147
  `token` varchar(100) NOT NULL COMMENT 'token',
148
  `expire_time` datetime COMMENT '过期时间',
149
  `update_time` datetime COMMENT '更新时间',
150
  PRIMARY KEY (`user_id`),
151
  UNIQUE INDEX (`token`)
152
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户Token';
153 145
154 146
-- 账号:13612345678  密码:admin
155 147
INSERT INTO `tb_user` (`username`, `mobile`, `password`, `create_time`) VALUES ('mark', '13612345678', '8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918', '2017-03-23 22:37:41');

+ 7 - 1
pom-war.xml

@ -20,7 +20,7 @@
20 20
        <java.version>1.8</java.version>
21 21
        <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
22 22
        <mysql.version>5.1.38</mysql.version>
23
        <druid.version>1.1.2</druid.version>
23
        <druid.version>1.1.3</druid.version>
24 24
        <quartz.version>2.3.0</quartz.version>
25 25
        <commons.lang.version>2.6</commons.lang.version>
26 26
        <commons.fileupload.version>1.3.1</commons.fileupload.version>
@ -28,6 +28,7 @@
28 28
        <commons.codec.version>1.10</commons.codec.version>
29 29
        <commons.configuration.version>1.10</commons.configuration.version>
30 30
        <shiro.version>1.3.2</shiro.version>
31
        <jwt.version>0.7.0</jwt.version>
31 32
        <kaptcha.version>0.0.9</kaptcha.version>
32 33
        <qiniu.version>[7.2.0, 7.2.99]</qiniu.version>
33 34
        <aliyun.oss.version>2.5.0</aliyun.oss.version>
@ -132,6 +133,11 @@
132 133
            <artifactId>shiro-spring</artifactId>
133 134
            <version>${shiro.version}</version>
134 135
        </dependency>
136
        <dependency>
137
            <groupId>io.jsonwebtoken</groupId>
138
            <artifactId>jjwt</artifactId>
139
            <version>${jwt.version}</version>
140
        </dependency>
135 141
        <dependency>
136 142
            <groupId>com.github.axet</groupId>
137 143
            <artifactId>kaptcha</artifactId>

+ 13 - 0
pom.xml

@ -28,6 +28,8 @@
28 28
		<commons.codec.version>1.10</commons.codec.version>
29 29
		<commons.configuration.version>1.10</commons.configuration.version>
30 30
		<shiro.version>1.3.2</shiro.version>
31
		<jwt.version>0.7.0</jwt.version>
32
		<kaptcha.version>0.0.9</kaptcha.version>
31 33
		<qiniu.version>[7.2.0, 7.2.99]</qiniu.version>
32 34
		<aliyun.oss.version>2.5.0</aliyun.oss.version>
33 35
		<qcloud.cos.version>4.4</qcloud.cos.version>
@ -133,6 +135,16 @@
133 135
			<artifactId>shiro-spring</artifactId>
134 136
			<version>${shiro.version}</version>
135 137
		</dependency>
138
		<dependency>
139
			<groupId>io.jsonwebtoken</groupId>
140
			<artifactId>jjwt</artifactId>
141
			<version>${jwt.version}</version>
142
		</dependency>
143
		<dependency>
144
			<groupId>com.github.axet</groupId>
145
			<artifactId>kaptcha</artifactId>
146
			<version>${kaptcha.version}</version>
147
		</dependency>
136 148
		<dependency>
137 149
			<groupId>com.qiniu</groupId>
138 150
			<artifactId>qiniu-java-sdk</artifactId>
@ -157,6 +169,7 @@
157 169
	</dependencies>
158 170
159 171
	<build>
172
		<finalName>${artifactId}</finalName>
160 173
		<extensions>
161 174
			<extension>
162 175
				<groupId>org.apache.maven.wagon</groupId>

+ 88 - 0
src/main/java/io/renren/common/utils/JwtUtils.java

@ -0,0 +1,88 @@
1
package io.renren.common.utils;
2
3
import io.jsonwebtoken.Claims;
4
import io.jsonwebtoken.Jwts;
5
import io.jsonwebtoken.SignatureAlgorithm;
6
import org.slf4j.Logger;
7
import org.slf4j.LoggerFactory;
8
import org.springframework.boot.context.properties.ConfigurationProperties;
9
import org.springframework.stereotype.Component;
10
11
import java.util.Date;
12
13
/**
14
 * jwt工具类
15
 * @author chenshun
16
 * @email sunlightcs@gmail.com
17
 * @date 2017/9/21 22:21
18
 */
19
@ConfigurationProperties(prefix = "renren.jwt")
20
@Component
21
public class JwtUtils {
22
    private Logger logger = LoggerFactory.getLogger(getClass());
23
24
    private String secret;
25
    private long expire;
26
    private String header;
27
28
    /**
29
     * 生成jwt token
30
     */
31
    public String generateToken(long userId) {
32
        Date nowDate = new Date();
33
        //过期时间
34
        Date expireDate = new Date(nowDate.getTime() + expire * 1000);
35
36
        return Jwts.builder()
37
                .setHeaderParam("typ", "JWT")
38
                .setSubject(userId+"")
39
                .setIssuedAt(nowDate)
40
                .setExpiration(expireDate)
41
                .signWith(SignatureAlgorithm.HS512, secret)
42
                .compact();
43
    }
44
45
    public Claims getClaimByToken(String token) {
46
        try {
47
            return Jwts.parser()
48
                    .setSigningKey(secret)
49
                    .parseClaimsJws(token)
50
                    .getBody();
51
        }catch (Exception e){
52
            logger.debug("validate is token error ", e);
53
            return null;
54
        }
55
    }
56
57
    /**
58
     * token是否过期
59
     * @return  true:过期
60
     */
61
    public boolean isTokenExpired(Date expiration) {
62
        return expiration.before(new Date());
63
    }
64
65
    public String getSecret() {
66
        return secret;
67
    }
68
69
    public void setSecret(String secret) {
70
        this.secret = secret;
71
    }
72
73
    public long getExpire() {
74
        return expire;
75
    }
76
77
    public void setExpire(long expire) {
78
        this.expire = expire;
79
    }
80
81
    public String getHeader() {
82
        return header;
83
    }
84
85
    public void setHeader(String header) {
86
        this.header = header;
87
    }
88
}

+ 1 - 0
src/main/java/io/renren/common/utils/R.java

@ -17,6 +17,7 @@ public class R extends HashMap<String, Object> {
17 17
	
18 18
	public R() {
19 19
		put("code", 0);
20
		put("msg", "success");
20 21
	}
21 22
	
22 23
	public static R error() {

+ 10 - 0
src/main/java/io/renren/common/utils/ShiroUtils.java

@ -1,5 +1,6 @@
1 1
package io.renren.common.utils;
2 2
3
import io.renren.common.exception.RRException;
3 4
import io.renren.modules.sys.entity.SysUserEntity;
4 5
import org.apache.shiro.SecurityUtils;
5 6
import org.apache.shiro.session.Session;
@ -42,4 +43,13 @@ public class ShiroUtils {
42 43
		return SecurityUtils.getSubject().getPrincipal() != null;
43 44
	}
44 45
46
	public static String getKaptcha(String key) {
47
		Object kaptcha = getSessionAttribute(key);
48
		if(kaptcha == null){
49
			throw new RRException("验证码已失效");
50
		}
51
		getSession().removeAttribute(key);
52
		return kaptcha.toString();
53
	}
54
45 55
}

+ 32 - 0
src/main/java/io/renren/config/KaptchaConfig.java

@ -0,0 +1,32 @@
1
package io.renren.config;
2
3
import com.google.code.kaptcha.impl.DefaultKaptcha;
4
import com.google.code.kaptcha.util.Config;
5
import org.springframework.context.annotation.Bean;
6
import org.springframework.context.annotation.Configuration;
7
8
import java.util.Properties;
9
10
11
/**
12
 * 生成验证码配置
13
 *
14
 * @author chenshun
15
 * @email sunlightcs@gmail.com
16
 * @date 2017-04-20 19:22
17
 */
18
@Configuration
19
public class KaptchaConfig {
20
21
    @Bean
22
    public DefaultKaptcha producer() {
23
        Properties properties = new Properties();
24
        properties.put("kaptcha.border", "no");
25
        properties.put("kaptcha.textproducer.font.color", "black");
26
        properties.put("kaptcha.textproducer.char.space", "5");
27
        Config config = new Config(properties);
28
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
29
        defaultKaptcha.setConfig(config);
30
        return defaultKaptcha;
31
    }
32
}

+ 3 - 2
src/main/java/io/renren/config/ShiroConfig.java

@ -32,7 +32,7 @@ public class ShiroConfig {
32 32
    public SessionManager sessionManager(){
33 33
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
34 34
        sessionManager.setSessionValidationSchedulerEnabled(true);
35
        sessionManager.setSessionIdCookieEnabled(false);
35
        sessionManager.setSessionIdCookieEnabled(true);
36 36
        return sessionManager;
37 37
    }
38 38
@ -58,7 +58,7 @@ public class ShiroConfig {
58 58
        Map<String, String> filterMap = new LinkedHashMap<>();
59 59
        filterMap.put("/webjars/**", "anon");
60 60
        filterMap.put("/druid/**", "anon");
61
        filterMap.put("/api/**", "anon");
61
        filterMap.put("/app/**", "anon");
62 62
        filterMap.put("/sys/login", "anon");
63 63
        filterMap.put("/**/*.css", "anon");
64 64
        filterMap.put("/**/*.js", "anon");
@ -67,6 +67,7 @@ public class ShiroConfig {
67 67
        filterMap.put("/plugins/**", "anon");
68 68
        filterMap.put("/swagger/**", "anon");
69 69
        filterMap.put("/favicon.ico", "anon");
70
        filterMap.put("/captcha.jpg", "anon");
70 71
        filterMap.put("/", "anon");
71 72
        filterMap.put("/**", "oauth2");
72 73
        shiroFilter.setFilterChainDefinitionMap(filterMap);

+ 14 - 0
src/main/java/io/renren/datasources/DataSourceNames.java

@ -0,0 +1,14 @@
1
package io.renren.datasources;
2
3
/**
4
 * 增加多数据源,在此配置
5
 *
6
 * @author chenshun
7
 * @email sunlightcs@gmail.com
8
 * @date 2017/8/18 23:46
9
 */
10
public interface DataSourceNames {
11
    String FIRST = "first";
12
    String SECOND = "second";
13
14
}

+ 28 - 0
src/main/java/io/renren/datasources/DataSourceTestService.java

@ -0,0 +1,28 @@
1
package io.renren.datasources;
2
3
import io.renren.datasources.annotation.DataSource;
4
import io.renren.modules.app.entity.UserEntity;
5
import io.renren.modules.app.service.UserService;
6
import org.springframework.beans.factory.annotation.Autowired;
7
import org.springframework.stereotype.Service;
8
9
/**
10
 * 测试
11
 * @author chenshun
12
 * @email sunlightcs@gmail.com
13
 * @date 2017/9/16 23:10
14
 */
15
@Service
16
public class DataSourceTestService {
17
    @Autowired
18
    private UserService userService;
19
20
    public UserEntity queryObject(Long userId){
21
        return userService.queryObject(userId);
22
    }
23
24
    @DataSource(name = DataSourceNames.SECOND)
25
    public UserEntity queryObject2(Long userId){
26
        return userService.queryObject(userId);
27
    }
28
}

+ 1 - 1
src/main/java/io/renren/dynamicdatasource/DynamicDataSource.java

@ -1,4 +1,4 @@
1
package io.renren.dynamicdatasource;
1
package io.renren.datasources;
2 2
3 3
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
4 4

+ 3 - 3
src/main/java/io/renren/dynamicdatasource/DynamicDataSourceConfig.java

@ -1,4 +1,4 @@
1
package io.renren.dynamicdatasource;
1
package io.renren.datasources;
2 2
3 3
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
4 4
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -35,8 +35,8 @@ public class DynamicDataSourceConfig {
35 35
    @Primary
36 36
    public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
37 37
        Map<String, DataSource> targetDataSources = new HashMap<>();
38
        targetDataSources.put(DataSourceContext.FIRST.getName(), firstDataSource);
39
        targetDataSources.put(DataSourceContext.SECOND.getName(), secondDataSource);
38
        targetDataSources.put(DataSourceNames.FIRST, firstDataSource);
39
        targetDataSources.put(DataSourceNames.SECOND, secondDataSource);
40 40
        return new DynamicDataSource(firstDataSource, targetDataSources);
41 41
    }
42 42
}

+ 16 - 0
src/main/java/io/renren/datasources/annotation/DataSource.java

@ -0,0 +1,16 @@
1
package io.renren.datasources.annotation;
2
3
import java.lang.annotation.*;
4
5
/**
6
 * 多数据源注解
7
 * @author chenshun
8
 * @email sunlightcs@gmail.com
9
 * @date 2017/9/16 22:16
10
 */
11
@Target(ElementType.METHOD)
12
@Retention(RetentionPolicy.RUNTIME)
13
@Documented
14
public @interface DataSource {
15
    String name() default "";
16
}

+ 60 - 0
src/main/java/io/renren/datasources/aspect/DataSourceAspect.java

@ -0,0 +1,60 @@
1
package io.renren.datasources.aspect;
2
3
import io.renren.datasources.DataSourceNames;
4
import io.renren.datasources.DynamicDataSource;
5
import io.renren.datasources.annotation.DataSource;
6
import org.aspectj.lang.ProceedingJoinPoint;
7
import org.aspectj.lang.annotation.Around;
8
import org.aspectj.lang.annotation.Aspect;
9
import org.aspectj.lang.annotation.Pointcut;
10
import org.aspectj.lang.reflect.MethodSignature;
11
import org.slf4j.Logger;
12
import org.slf4j.LoggerFactory;
13
import org.springframework.core.Ordered;
14
import org.springframework.stereotype.Component;
15
16
import java.lang.reflect.Method;
17
18
/**
19
 * 多数据源,切面处理类
20
 * @author chenshun
21
 * @email sunlightcs@gmail.com
22
 * @date 2017/9/16 22:20
23
 */
24
@Aspect
25
@Component
26
public class DataSourceAspect implements Ordered {
27
    protected Logger logger = LoggerFactory.getLogger(getClass());
28
29
    @Pointcut("@annotation(io.renren.datasources.annotation.DataSource)")
30
    public void dataSourcePointCut() {
31
32
    }
33
34
    @Around("dataSourcePointCut()")
35
    public Object around(ProceedingJoinPoint point) throws Throwable {
36
        MethodSignature signature = (MethodSignature) point.getSignature();
37
        Method method = signature.getMethod();
38
39
        DataSource ds = method.getAnnotation(DataSource.class);
40
        if(ds == null){
41
            DynamicDataSource.setDataSource(DataSourceNames.FIRST);
42
            logger.debug("set datasource is " + DataSourceNames.FIRST);
43
        }else {
44
            DynamicDataSource.setDataSource(ds.name());
45
            logger.debug("set datasource is " + ds.name());
46
        }
47
48
        try {
49
            return point.proceed();
50
        } finally {
51
            DynamicDataSource.clearDataSource();
52
            logger.debug("clean datasource");
53
        }
54
    }
55
56
    @Override
57
    public int getOrder() {
58
        return 1;
59
    }
60
}

+ 0 - 23
src/main/java/io/renren/dynamicdatasource/DataSourceContext.java

@ -1,23 +0,0 @@
1
package io.renren.dynamicdatasource;
2
3
/**
4
 * 增加多数据源,在此配置
5
 *
6
 * @author chenshun
7
 * @email sunlightcs@gmail.com
8
 * @date 2017/8/18 23:46
9
 */
10
public enum DataSourceContext {
11
    FIRST("first"),
12
    SECOND("second");
13
14
    private String name;
15
16
    DataSourceContext(String name) {
17
        this.name = name;
18
    }
19
20
    public String getName() {
21
        return name;
22
    }
23
}

+ 0 - 46
src/main/java/io/renren/modules/api/controller/ApiTestController.java

@ -1,46 +0,0 @@
1
package io.renren.modules.api.controller;
2
3
4
import io.renren.common.utils.R;
5
import io.renren.modules.api.annotation.AuthIgnore;
6
import io.renren.modules.api.annotation.LoginUser;
7
import io.renren.modules.api.entity.TokenEntity;
8
import io.renren.modules.api.entity.UserEntity;
9
import org.springframework.web.bind.annotation.*;
10
11
/**
12
 * API测试接口
13
 *
14
 * @author chenshun
15
 * @email sunlightcs@gmail.com
16
 * @date 2017-03-23 15:47
17
 */
18
@RestController
19
@RequestMapping("/api")
20
public class ApiTestController {
21
22
    /**
23
     * 获取用户信息
24
     */
25
    @GetMapping("userInfo")
26
    public R userInfo(@LoginUser UserEntity user){
27
        return R.ok().put("user", user);
28
    }
29
30
    /**
31
     * 忽略Token验证测试
32
     */
33
    @AuthIgnore
34
    @GetMapping("notToken")
35
    public R notToken(){
36
        return R.ok().put("msg", "无需token也能访问。。。");
37
    }
38
39
    /**
40
     * 接收JSON数据
41
     */
42
    @PostMapping("jsonData")
43
    public R jsonData(@LoginUser UserEntity user, @RequestBody TokenEntity token){
44
        return R.ok().put("user", user).put("token", token);
45
    }
46
}

+ 0 - 21
src/main/java/io/renren/modules/api/dao/TokenDao.java

@ -1,21 +0,0 @@
1
package io.renren.modules.api.dao;
2
3
import io.renren.modules.api.entity.TokenEntity;
4
import io.renren.modules.sys.dao.BaseDao;
5
import org.apache.ibatis.annotations.Mapper;
6
7
/**
8
 * 用户Token
9
 * 
10
 * @author chenshun
11
 * @email sunlightcs@gmail.com
12
 * @date 2017-03-23 15:22:07
13
 */
14
@Mapper
15
public interface TokenDao extends BaseDao<TokenEntity> {
16
    
17
    TokenEntity queryByUserId(Long userId);
18
19
    TokenEntity queryByToken(String token);
20
	
21
}

+ 0 - 75
src/main/java/io/renren/modules/api/entity/TokenEntity.java

@ -1,75 +0,0 @@
1
package io.renren.modules.api.entity;
2
3
import java.io.Serializable;
4
import java.util.Date;
5
6
7
8
/**
9
 * 用户Token
10
 * 
11
 * @author chenshun
12
 * @email sunlightcs@gmail.com
13
 * @date 2017-03-23 15:22:07
14
 */
15
public class TokenEntity implements Serializable {
16
	private static final long serialVersionUID = 1L;
17
	
18
	//用户ID
19
	private Long userId;
20
	//token
21
	private String token;
22
	//过期时间
23
	private Date expireTime;
24
	//更新时间
25
	private Date updateTime;
26
27
	/**
28
	 * 设置:用户ID
29
	 */
30
	public void setUserId(Long userId) {
31
		this.userId = userId;
32
	}
33
	/**
34
	 * 获取:用户ID
35
	 */
36
	public Long getUserId() {
37
		return userId;
38
	}
39
	/**
40
	 * 设置:token
41
	 */
42
	public void setToken(String token) {
43
		this.token = token;
44
	}
45
	/**
46
	 * 获取:token
47
	 */
48
	public String getToken() {
49
		return token;
50
	}
51
	/**
52
	 * 设置:过期时间
53
	 */
54
	public void setExpireTime(Date expireTime) {
55
		this.expireTime = expireTime;
56
	}
57
	/**
58
	 * 获取:过期时间
59
	 */
60
	public Date getExpireTime() {
61
		return expireTime;
62
	}
63
	/**
64
	 * 设置:更新时间
65
	 */
66
	public void setUpdateTime(Date updateTime) {
67
		this.updateTime = updateTime;
68
	}
69
	/**
70
	 * 获取:更新时间
71
	 */
72
	public Date getUpdateTime() {
73
		return updateTime;
74
	}
75
}

+ 0 - 32
src/main/java/io/renren/modules/api/service/TokenService.java

@ -1,32 +0,0 @@
1
package io.renren.modules.api.service;
2
3
4
import io.renren.modules.api.entity.TokenEntity;
5
6
import java.util.Map;
7
8
/**
9
 * 用户Token
10
 * 
11
 * @author chenshun
12
 * @email sunlightcs@gmail.com
13
 * @date 2017-03-23 15:22:07
14
 */
15
public interface TokenService {
16
17
	TokenEntity queryByUserId(Long userId);
18
19
	TokenEntity queryByToken(String token);
20
	
21
	void save(TokenEntity token);
22
	
23
	void update(TokenEntity token);
24
25
	/**
26
	 * 生成token
27
	 * @param userId  用户ID
28
	 * @return        返回token相关信息
29
	 */
30
	Map<String, Object> createToken(long userId);
31
32
}

+ 0 - 80
src/main/java/io/renren/modules/api/service/impl/TokenServiceImpl.java

@ -1,80 +0,0 @@
1
package io.renren.modules.api.service.impl;
2
3
import org.springframework.stereotype.Service;
4
5
6
import io.renren.modules.api.dao.TokenDao;
7
import io.renren.modules.api.entity.TokenEntity;
8
import io.renren.modules.api.service.TokenService;
9
import org.springframework.beans.factory.annotation.Autowired;
10
11
import java.util.Date;
12
import java.util.HashMap;
13
import java.util.Map;
14
import java.util.UUID;
15
16
17
@Service("tokenService")
18
public class TokenServiceImpl implements TokenService {
19
	@Autowired
20
	private TokenDao tokenDao;
21
	//12小时后过期
22
	private final static int EXPIRE = 3600 * 12;
23
24
	@Override
25
	public TokenEntity queryByUserId(Long userId) {
26
		return tokenDao.queryByUserId(userId);
27
	}
28
29
	@Override
30
	public TokenEntity queryByToken(String token) {
31
		return tokenDao.queryByToken(token);
32
	}
33
34
	@Override
35
	public void save(TokenEntity token){
36
		tokenDao.save(token);
37
	}
38
	
39
	@Override
40
	public void update(TokenEntity token){
41
		tokenDao.update(token);
42
	}
43
44
	@Override
45
	public Map<String, Object> createToken(long userId) {
46
		//生成一个token
47
		String token = UUID.randomUUID().toString();
48
		//当前时间
49
		Date now = new Date();
50
51
		//过期时间
52
		Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
53
54
		//判断是否生成过token
55
		TokenEntity tokenEntity = queryByUserId(userId);
56
		if(tokenEntity == null){
57
			tokenEntity = new TokenEntity();
58
			tokenEntity.setUserId(userId);
59
			tokenEntity.setToken(token);
60
			tokenEntity.setUpdateTime(now);
61
			tokenEntity.setExpireTime(expireTime);
62
63
			//保存token
64
			save(tokenEntity);
65
		}else{
66
			tokenEntity.setToken(token);
67
			tokenEntity.setUpdateTime(now);
68
			tokenEntity.setExpireTime(expireTime);
69
70
			//更新token
71
			update(tokenEntity);
72
		}
73
74
		Map<String, Object> map = new HashMap<>();
75
		map.put("token", token);
76
		map.put("expire", EXPIRE);
77
78
		return map;
79
	}
80
}

+ 4 - 5
src/main/java/io/renren/modules/api/annotation/AuthIgnore.java

@ -1,16 +1,15 @@
1
package io.renren.modules.api.annotation;
1
package io.renren.modules.app.annotation;
2 2
3 3
import java.lang.annotation.*;
4 4
5 5
/**
6
 * api接口,忽略Token验证
6
 * app登录效验
7 7
 * @author chenshun
8 8
 * @email sunlightcs@gmail.com
9
 * @date 2017-03-23 15:44
9
 * @date 2017/9/23 14:30
10 10
 */
11 11
@Target(ElementType.METHOD)
12 12
@Retention(RetentionPolicy.RUNTIME)
13 13
@Documented
14
public @interface AuthIgnore {
15
14
public @interface Login {
16 15
}

+ 1 - 1
src/main/java/io/renren/modules/api/annotation/LoginUser.java

@ -1,4 +1,4 @@
1
package io.renren.modules.api.annotation;
1
package io.renren.modules.app.annotation;
2 2
3 3
import java.lang.annotation.ElementType;
4 4
import java.lang.annotation.Retention;

+ 4 - 4
src/main/java/io/renren/modules/api/config/WebMvcConfig.java

@ -1,7 +1,7 @@
1
package io.renren.modules.api.config;
1
package io.renren.modules.app.config;
2 2
3
import io.renren.modules.api.interceptor.AuthorizationInterceptor;
4
import io.renren.modules.api.resolver.LoginUserHandlerMethodArgumentResolver;
3
import io.renren.modules.app.interceptor.AuthorizationInterceptor;
4
import io.renren.modules.app.resolver.LoginUserHandlerMethodArgumentResolver;
5 5
import org.springframework.beans.factory.annotation.Autowired;
6 6
import org.springframework.context.annotation.Configuration;
7 7
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
@ -26,7 +26,7 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter {
26 26
27 27
    @Override
28 28
    public void addInterceptors(InterceptorRegistry registry) {
29
        registry.addInterceptor(authorizationInterceptor).addPathPatterns("/api/**");
29
        registry.addInterceptor(authorizationInterceptor).addPathPatterns("/app/**");
30 30
    }
31 31
32 32
    @Override

+ 12 - 9
src/main/java/io/renren/modules/api/controller/ApiLoginController.java

@ -1,37 +1,36 @@
1
package io.renren.modules.api.controller;
1
package io.renren.modules.app.controller;
2 2
3 3
4
import io.renren.common.utils.JwtUtils;
4 5
import io.renren.common.utils.R;
5 6
import io.renren.common.validator.Assert;
6
import io.renren.modules.api.annotation.AuthIgnore;
7
import io.renren.modules.api.service.TokenService;
8
import io.renren.modules.api.service.UserService;
7
import io.renren.modules.app.service.UserService;
9 8
import org.springframework.beans.factory.annotation.Autowired;
10 9
import org.springframework.web.bind.annotation.PostMapping;
11 10
import org.springframework.web.bind.annotation.RequestMapping;
12 11
import org.springframework.web.bind.annotation.RestController;
13 12
13
import java.util.HashMap;
14 14
import java.util.Map;
15 15
16 16
/**
17
 * API登录授权
17
 * APP登录授权
18 18
 *
19 19
 * @author chenshun
20 20
 * @email sunlightcs@gmail.com
21 21
 * @date 2017-03-23 15:31
22 22
 */
23 23
@RestController
24
@RequestMapping("/api")
24
@RequestMapping("/app")
25 25
public class ApiLoginController {
26 26
    @Autowired
27 27
    private UserService userService;
28 28
    @Autowired
29
    private TokenService tokenService;
29
    private JwtUtils jwtUtils;
30 30
31 31
    /**
32 32
     * 登录
33 33
     */
34
    @AuthIgnore
35 34
    @PostMapping("login")
36 35
    public R login(String mobile, String password){
37 36
        Assert.isBlank(mobile, "手机号不能为空");
@ -41,7 +40,11 @@ public class ApiLoginController {
41 40
        long userId = userService.login(mobile, password);
42 41
43 42
        //生成token
44
        Map<String, Object> map = tokenService.createToken(userId);
43
        String token = jwtUtils.generateToken(userId);
44
45
        Map<String, Object> map = new HashMap<>();
46
        map.put("token", token);
47
        map.put("expire", jwtUtils.getExpire());
45 48
46 49
        return R.ok(map);
47 50
    }

+ 3 - 5
src/main/java/io/renren/modules/api/controller/ApiRegisterController.java

@ -1,10 +1,9 @@
1
package io.renren.modules.api.controller;
1
package io.renren.modules.app.controller;
2 2
3 3
4 4
import io.renren.common.utils.R;
5 5
import io.renren.common.validator.Assert;
6
import io.renren.modules.api.annotation.AuthIgnore;
7
import io.renren.modules.api.service.UserService;
6
import io.renren.modules.app.service.UserService;
8 7
import org.springframework.beans.factory.annotation.Autowired;
9 8
import org.springframework.web.bind.annotation.PostMapping;
10 9
import org.springframework.web.bind.annotation.RequestMapping;
@ -17,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
17 16
 * @date 2017-03-26 17:27
18 17
 */
19 18
@RestController
20
@RequestMapping("/api")
19
@RequestMapping("/app")
21 20
public class ApiRegisterController {
22 21
    @Autowired
23 22
    private UserService userService;
@ -25,7 +24,6 @@ public class ApiRegisterController {
25 24
    /**
26 25
     * 注册
27 26
     */
28
    @AuthIgnore
29 27
    @PostMapping("register")
30 28
    public R register(String mobile, String password){
31 29
        Assert.isBlank(mobile, "手机号不能为空");

+ 50 - 0
src/main/java/io/renren/modules/app/controller/ApiTestController.java

@ -0,0 +1,50 @@
1
package io.renren.modules.app.controller;
2
3
4
import io.renren.common.utils.R;
5
import io.renren.modules.app.annotation.Login;
6
import io.renren.modules.app.annotation.LoginUser;
7
import io.renren.modules.app.entity.UserEntity;
8
import org.springframework.web.bind.annotation.GetMapping;
9
import org.springframework.web.bind.annotation.RequestAttribute;
10
import org.springframework.web.bind.annotation.RequestMapping;
11
import org.springframework.web.bind.annotation.RestController;
12
13
/**
14
 * APP测试接口
15
 *
16
 * @author chenshun
17
 * @email sunlightcs@gmail.com
18
 * @date 2017-03-23 15:47
19
 */
20
@RestController
21
@RequestMapping("/app")
22
public class ApiTestController {
23
24
    /**
25
     * 获取用户信息
26
     */
27
    @Login
28
    @GetMapping("userInfo")
29
    public R userInfo(@LoginUser UserEntity user){
30
        return R.ok().put("user", user);
31
    }
32
33
    /**
34
     * 获取用户ID
35
     */
36
    @Login
37
    @GetMapping("userId")
38
    public R userInfo(@RequestAttribute("userId") Integer userId){
39
        return R.ok().put("userId", userId);
40
    }
41
42
    /**
43
     * 忽略Token验证测试
44
     */
45
    @GetMapping("notToken")
46
    public R notToken(){
47
        return R.ok().put("msg", "无需token也能访问。。。");
48
    }
49
50
}

+ 2 - 2
src/main/java/io/renren/modules/api/dao/UserDao.java

@ -1,6 +1,6 @@
1
package io.renren.modules.api.dao;
1
package io.renren.modules.app.dao;
2 2
3
import io.renren.modules.api.entity.UserEntity;
3
import io.renren.modules.app.entity.UserEntity;
4 4
import io.renren.modules.sys.dao.BaseDao;
5 5
import org.apache.ibatis.annotations.Mapper;
6 6

+ 1 - 1
src/main/java/io/renren/modules/api/entity/UserEntity.java

@ -1,4 +1,4 @@
1
package io.renren.modules.api.entity;
1
package io.renren.modules.app.entity;
2 2
3 3
import java.io.Serializable;
4 4
import java.util.Date;

+ 19 - 21
src/main/java/io/renren/modules/api/interceptor/AuthorizationInterceptor.java

@ -1,12 +1,13 @@
1
package io.renren.modules.api.interceptor;
1
package io.renren.modules.app.interceptor;
2 2
3 3
4
import io.jsonwebtoken.Claims;
4 5
import io.renren.common.exception.RRException;
5
import io.renren.modules.api.annotation.AuthIgnore;
6
import io.renren.modules.api.entity.TokenEntity;
7
import io.renren.modules.api.service.TokenService;
6
import io.renren.common.utils.JwtUtils;
7
import io.renren.modules.app.annotation.Login;
8 8
import org.apache.commons.lang.StringUtils;
9 9
import org.springframework.beans.factory.annotation.Autowired;
10
import org.springframework.http.HttpStatus;
10 11
import org.springframework.stereotype.Component;
11 12
import org.springframework.web.method.HandlerMethod;
12 13
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@ -23,44 +24,41 @@ import javax.servlet.http.HttpServletResponse;
23 24
@Component
24 25
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
25 26
    @Autowired
26
    private TokenService tokenService;
27
    private JwtUtils jwtUtils;
27 28
28
    public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";
29
    public static final String USER_KEY = "userId";
29 30
30 31
    @Override
31 32
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
32
        AuthIgnore annotation;
33
        Login annotation;
33 34
        if(handler instanceof HandlerMethod) {
34
            annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthIgnore.class);
35
            annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class);
35 36
        }else{
36 37
            return true;
37 38
        }
38 39
39
        //如果有@AuthIgnore注解,则不验证token
40
        if(annotation != null){
40
        if(annotation == null){
41 41
            return true;
42 42
        }
43 43
44
        //从header中获取token
45
        String token = request.getHeader("token");
46
        //如果header中不存在token,则从参数中获取token
44
        //获取用户凭证
45
        String token = request.getHeader(jwtUtils.getHeader());
47 46
        if(StringUtils.isBlank(token)){
48
            token = request.getParameter("token");
47
            token = request.getParameter(jwtUtils.getHeader());
49 48
        }
50 49
51
        //token为空
50
        //凭证为空
52 51
        if(StringUtils.isBlank(token)){
53
            throw new RRException("token不能为空");
52
            throw new RRException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value());
54 53
        }
55 54
56
        //查询token信息
57
        TokenEntity tokenEntity = tokenService.queryByToken(token);
58
        if(tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()){
59
            throw new RRException("token失效,请重新登录");
55
        Claims claims = jwtUtils.getClaimByToken(token);
56
        if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){
57
            throw new RRException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value());
60 58
        }
61 59
62 60
        //设置userId到request里,后续根据userId,获取用户信息
63
        request.setAttribute(LOGIN_USER_KEY, tokenEntity.getUserId());
61
        request.setAttribute(USER_KEY, Long.parseLong(claims.getSubject()));
64 62
65 63
        return true;
66 64
    }

+ 6 - 6
src/main/java/io/renren/modules/api/resolver/LoginUserHandlerMethodArgumentResolver.java

@ -1,9 +1,9 @@
1
package io.renren.modules.api.resolver;
1
package io.renren.modules.app.resolver;
2 2
3
import io.renren.modules.api.annotation.LoginUser;
4
import io.renren.modules.api.entity.UserEntity;
5
import io.renren.modules.api.interceptor.AuthorizationInterceptor;
6
import io.renren.modules.api.service.UserService;
3
import io.renren.modules.app.annotation.LoginUser;
4
import io.renren.modules.app.entity.UserEntity;
5
import io.renren.modules.app.interceptor.AuthorizationInterceptor;
6
import io.renren.modules.app.service.UserService;
7 7
import org.springframework.beans.factory.annotation.Autowired;
8 8
import org.springframework.core.MethodParameter;
9 9
import org.springframework.stereotype.Component;
@ -33,7 +33,7 @@ public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgu
33 33
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
34 34
                                  NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
35 35
        //获取用户ID
36
        Object object = request.getAttribute(AuthorizationInterceptor.LOGIN_USER_KEY, RequestAttributes.SCOPE_REQUEST);
36
        Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
37 37
        if(object == null){
38 38
            return null;
39 39
        }

+ 2 - 2
src/main/java/io/renren/modules/api/service/UserService.java

@ -1,7 +1,7 @@
1
package io.renren.modules.api.service;
1
package io.renren.modules.app.service;
2 2
3 3
4
import io.renren.modules.api.entity.UserEntity;
4
import io.renren.modules.app.entity.UserEntity;
5 5
6 6
import java.util.List;
7 7
import java.util.Map;

+ 4 - 4
src/main/java/io/renren/modules/api/service/impl/UserServiceImpl.java

@ -1,11 +1,11 @@
1
package io.renren.modules.api.service.impl;
1
package io.renren.modules.app.service.impl;
2 2
3 3
4 4
import io.renren.common.exception.RRException;
5 5
import io.renren.common.validator.Assert;
6
import io.renren.modules.api.dao.UserDao;
7
import io.renren.modules.api.entity.UserEntity;
8
import io.renren.modules.api.service.UserService;
6
import io.renren.modules.app.dao.UserDao;
7
import io.renren.modules.app.entity.UserEntity;
8
import io.renren.modules.app.service.UserService;
9 9
import org.apache.commons.codec.digest.DigestUtils;
10 10
import org.springframework.beans.factory.annotation.Autowired;
11 11
import org.springframework.stereotype.Service;

+ 1 - 1
src/main/java/io/renren/modules/job/utils/ScheduleUtils.java

@ -59,7 +59,7 @@ public class ScheduleUtils {
59 59
60 60
            //放入参数,运行时的方法可以获取
61 61
            jobDetail.getJobDataMap().put(ScheduleJobEntity.JOB_PARAM_KEY, new Gson().toJson(scheduleJob));
62
            
62
63 63
            scheduler.scheduleJob(jobDetail, trigger);
64 64
            
65 65
            //暂停任务

+ 5 - 5
src/main/java/io/renren/modules/oss/cloud/AliyunCloudStorageService.java

@ -12,7 +12,7 @@ import java.io.InputStream;
12 12
 * @email sunlightcs@gmail.com
13 13
 * @date 2017-03-26 16:22
14 14
 */
15
public class AliyunCloudStorageService extends CloudStorageService{
15
public class AliyunCloudStorageService extends CloudStorageService {
16 16
    private OSSClient client;
17 17
18 18
    public AliyunCloudStorageService(CloudStorageConfig config){
@ -44,12 +44,12 @@ public class AliyunCloudStorageService extends CloudStorageService{
44 44
    }
45 45
46 46
    @Override
47
    public String upload(byte[] data) {
48
        return upload(data, getPath(config.getAliyunPrefix()));
47
    public String uploadSuffix(byte[] data, String suffix) {
48
        return upload(data, getPath(config.getAliyunPrefix(), suffix));
49 49
    }
50 50
51 51
    @Override
52
    public String upload(InputStream inputStream) {
53
        return upload(inputStream, getPath(config.getAliyunPrefix()));
52
    public String uploadSuffix(InputStream inputStream, String suffix) {
53
        return upload(inputStream, getPath(config.getAliyunPrefix(), suffix));
54 54
    }
55 55
}

+ 9 - 6
src/main/java/io/renren/modules/oss/cloud/CloudStorageService.java

@ -20,9 +20,10 @@ public abstract class CloudStorageService {
20 20
    /**
21 21
     * 文件路径
22 22
     * @param prefix 前缀
23
     * @param suffix 后缀
23 24
     * @return 返回上传路径
24 25
     */
25
    public String getPath(String prefix) {
26
    public String getPath(String prefix, String suffix) {
26 27
        //生成uuid
27 28
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
28 29
        //文件路径
@ -32,7 +33,7 @@ public abstract class CloudStorageService {
32 33
            path = prefix + "/" + path;
33 34
        }
34 35
35
        return path;
36
        return path + suffix;
36 37
    }
37 38
38 39
    /**
@ -45,10 +46,11 @@ public abstract class CloudStorageService {
45 46
46 47
    /**
47 48
     * 文件上传
48
     * @param data    文件字节数组
49
     * @return        返回http地址
49
     * @param data     文件字节数组
50
     * @param suffix   后缀
51
     * @return         返回http地址
50 52
     */
51
    public abstract String upload(byte[] data);
53
    public abstract String uploadSuffix(byte[] data, String suffix);
52 54
53 55
    /**
54 56
     * 文件上传
@ -61,8 +63,9 @@ public abstract class CloudStorageService {
61 63
    /**
62 64
     * 文件上传
63 65
     * @param inputStream  字节流
66
     * @param suffix       后缀
64 67
     * @return             返回http地址
65 68
     */
66
    public abstract String upload(InputStream inputStream);
69
    public abstract String uploadSuffix(InputStream inputStream, String suffix);
67 70
68 71
}

+ 20 - 20
src/main/java/io/renren/modules/oss/cloud/QcloudCloudStorageService.java

@ -2,15 +2,15 @@ package io.renren.modules.oss.cloud;
2 2
3 3
4 4
import com.qcloud.cos.COSClient;
5
        import com.qcloud.cos.ClientConfig;
6
        import com.qcloud.cos.request.UploadFileRequest;
7
        import com.qcloud.cos.sign.Credentials;
8
        import io.renren.common.exception.RRException;
9
        import net.sf.json.JSONObject;
10
        import org.apache.commons.io.IOUtils;
5
import com.qcloud.cos.ClientConfig;
6
import com.qcloud.cos.request.UploadFileRequest;
7
import com.qcloud.cos.sign.Credentials;
8
import io.renren.common.exception.RRException;
9
import net.sf.json.JSONObject;
10
import org.apache.commons.io.IOUtils;
11 11
12
        import java.io.IOException;
13
        import java.io.InputStream;
12
import java.io.IOException;
13
import java.io.InputStream;
14 14
15 15
/**
16 16
 * 腾讯云存储
@ -18,7 +18,7 @@ import com.qcloud.cos.COSClient;
18 18
 * @email sunlightcs@gmail.com
19 19
 * @date 2017-03-26 20:51
20 20
 */
21
public class QcloudCloudStorageService extends CloudStorageService{
21
public class QcloudCloudStorageService extends CloudStorageService {
22 22
    private COSClient client;
23 23
24 24
    public QcloudCloudStorageService(CloudStorageConfig config){
@ -29,15 +29,15 @@ public class QcloudCloudStorageService extends CloudStorageService{
29 29
    }
30 30
31 31
    private void init(){
32
        Credentials credentials = new Credentials(config.getQcloudAppId(), config.getQcloudSecretId(),
32
    	Credentials credentials = new Credentials(config.getQcloudAppId(), config.getQcloudSecretId(),
33 33
                config.getQcloudSecretKey());
34
35
        //初始化客户端配置
34
    	
35
    	//初始化客户端配置
36 36
        ClientConfig clientConfig = new ClientConfig();
37 37
        //设置bucket所在的区域,华南:gz 华北:tj 华东:sh
38 38
        clientConfig.setRegion(config.getQcloudRegion());
39
40
        client = new COSClient(clientConfig, credentials);
39
        
40
    	client = new COSClient(clientConfig, credentials);
41 41
    }
42 42
43 43
    @Override
@ -46,7 +46,7 @@ public class QcloudCloudStorageService extends CloudStorageService{
46 46
        if(!path.startsWith("/")) {
47 47
            path = "/" + path;
48 48
        }
49
49
        
50 50
        //上传到腾讯云
51 51
        UploadFileRequest request = new UploadFileRequest(config.getQcloudBucketName(), path, data);
52 52
        String response = client.uploadFile(request);
@ -61,7 +61,7 @@ public class QcloudCloudStorageService extends CloudStorageService{
61 61
62 62
    @Override
63 63
    public String upload(InputStream inputStream, String path) {
64
        try {
64
    	try {
65 65
            byte[] data = IOUtils.toByteArray(inputStream);
66 66
            return this.upload(data, path);
67 67
        } catch (IOException e) {
@ -70,12 +70,12 @@ public class QcloudCloudStorageService extends CloudStorageService{
70 70
    }
71 71
72 72
    @Override
73
    public String upload(byte[] data) {
74
        return upload(data, getPath(config.getQcloudPrefix()));
73
    public String uploadSuffix(byte[] data, String suffix) {
74
        return upload(data, getPath(config.getQcloudPrefix(), suffix));
75 75
    }
76 76
77 77
    @Override
78
    public String upload(InputStream inputStream) {
79
        return upload(inputStream, getPath(config.getQcloudPrefix()));
78
    public String uploadSuffix(InputStream inputStream, String suffix) {
79
        return upload(inputStream, getPath(config.getQcloudPrefix(), suffix));
80 80
    }
81 81
}

+ 5 - 5
src/main/java/io/renren/modules/oss/cloud/QiniuCloudStorageService.java

@ -17,7 +17,7 @@ import java.io.InputStream;
17 17
 * @email sunlightcs@gmail.com
18 18
 * @date 2017-03-25 15:41
19 19
 */
20
public class QiniuCloudStorageService extends CloudStorageService{
20
public class QiniuCloudStorageService extends CloudStorageService {
21 21
    private UploadManager uploadManager;
22 22
    private String token;
23 23
@ -59,12 +59,12 @@ public class QiniuCloudStorageService extends CloudStorageService{
59 59
    }
60 60
61 61
    @Override
62
    public String upload(byte[] data) {
63
        return upload(data, getPath(config.getQiniuPrefix()));
62
    public String uploadSuffix(byte[] data, String suffix) {
63
        return upload(data, getPath(config.getQiniuPrefix(), suffix));
64 64
    }
65 65
66 66
    @Override
67
    public String upload(InputStream inputStream) {
68
        return upload(inputStream, getPath(config.getQiniuPrefix()));
67
    public String uploadSuffix(InputStream inputStream, String suffix) {
68
        return upload(inputStream, getPath(config.getQiniuPrefix(), suffix));
69 69
    }
70 70
}

+ 7 - 7
src/main/java/io/renren/modules/oss/controller/SysOssController.java

@ -2,16 +2,16 @@ package io.renren.modules.oss.controller;
2 2
3 3
import com.google.gson.Gson;
4 4
import io.renren.common.exception.RRException;
5
import io.renren.modules.oss.entity.SysOssEntity;
6
import io.renren.modules.sys.service.SysConfigService;
7
import io.renren.modules.oss.service.SysOssService;
8 5
import io.renren.common.utils.*;
9
import io.renren.modules.oss.cloud.CloudStorageConfig;
10
import io.renren.modules.oss.cloud.OSSFactory;
11 6
import io.renren.common.validator.ValidatorUtils;
12 7
import io.renren.common.validator.group.AliyunGroup;
13 8
import io.renren.common.validator.group.QcloudGroup;
14 9
import io.renren.common.validator.group.QiniuGroup;
10
import io.renren.modules.oss.cloud.CloudStorageConfig;
11
import io.renren.modules.oss.cloud.OSSFactory;
12
import io.renren.modules.oss.entity.SysOssEntity;
13
import io.renren.modules.oss.service.SysOssService;
14
import io.renren.modules.sys.service.SysConfigService;
15 15
import org.apache.shiro.authz.annotation.RequiresPermissions;
16 16
import org.springframework.beans.factory.annotation.Autowired;
17 17
import org.springframework.web.bind.annotation.RequestBody;
@ -25,7 +25,6 @@ import java.util.List;
25 25
import java.util.Map;
26 26
27 27
28
29 28
/**
30 29
 * 文件上传
31 30
 * 
@ -110,7 +109,8 @@ public class SysOssController {
110 109
		}
111 110
112 111
		//上传文件
113
		String url = OSSFactory.build().upload(file.getBytes());
112
		String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
113
		String url = OSSFactory.build().uploadSuffix(file.getBytes(), suffix);
114 114
115 115
		//保存文件信息
116 116
		SysOssEntity ossEntity = new SysOssEntity();

+ 40 - 1
src/main/java/io/renren/modules/sys/controller/SysLoginController.java

@ -1,15 +1,24 @@
1 1
package io.renren.modules.sys.controller;
2 2
3
import com.google.code.kaptcha.Constants;
4
import com.google.code.kaptcha.Producer;
3 5
import io.renren.common.utils.R;
6
import io.renren.common.utils.ShiroUtils;
4 7
import io.renren.modules.sys.entity.SysUserEntity;
5 8
import io.renren.modules.sys.service.SysUserService;
6 9
import io.renren.modules.sys.service.SysUserTokenService;
10
import org.apache.commons.io.IOUtils;
7 11
import org.apache.shiro.crypto.hash.Sha256Hash;
8 12
import org.springframework.beans.factory.annotation.Autowired;
9 13
import org.springframework.web.bind.annotation.RequestMapping;
10 14
import org.springframework.web.bind.annotation.RequestMethod;
11 15
import org.springframework.web.bind.annotation.RestController;
12 16
17
import javax.imageio.ImageIO;
18
import javax.servlet.ServletException;
19
import javax.servlet.ServletOutputStream;
20
import javax.servlet.http.HttpServletResponse;
21
import java.awt.image.BufferedImage;
13 22
import java.io.IOException;
14 23
import java.util.Map;
15 24
@ -22,16 +31,45 @@ import java.util.Map;
22 31
 */
23 32
@RestController
24 33
public class SysLoginController extends AbstractController {
34
	@Autowired
35
	private Producer producer;
25 36
	@Autowired
26 37
	private SysUserService sysUserService;
27 38
	@Autowired
28 39
	private SysUserTokenService sysUserTokenService;
29 40
41
	/**
42
	 * 验证码
43
	 */
44
	@RequestMapping("captcha.jpg")
45
	public void captcha(HttpServletResponse response)throws ServletException, IOException {
46
		response.setHeader("Cache-Control", "no-store, no-cache");
47
		response.setContentType("image/jpeg");
48
49
		//生成文字验证码
50
		String text = producer.createText();
51
		//生成图片验证码
52
		BufferedImage image = producer.createImage(text);
53
		//保存到shiro session
54
		ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);
55
56
		ServletOutputStream out = response.getOutputStream();
57
		ImageIO.write(image, "jpg", out);
58
		IOUtils.closeQuietly(out);
59
	}
60
30 61
	/**
31 62
	 * 登录
32 63
	 */
33 64
	@RequestMapping(value = "/sys/login", method = RequestMethod.POST)
34
	public Map<String, Object> login(String username, String password)throws IOException {
65
	public Map<String, Object> login(String username, String password, String captcha)throws IOException {
66
		//本项目已实现,前后端完全分离,但页面还是跟项目放在一起了,所以还是会依赖session
67
		//如果想把页面单独放到nginx里,实现前后端完全分离,则需要把验证码注释掉(因为不再依赖session了)
68
		String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
69
		if(!captcha.equalsIgnoreCase(kaptcha)){
70
			return R.error("验证码不正确");
71
		}
72
35 73
		//用户信息
36 74
		SysUserEntity user = sysUserService.queryByUserName(username);
37 75
@ -50,6 +88,7 @@ public class SysLoginController extends AbstractController {
50 88
		return r;
51 89
	}
52 90
91
53 92
	/**
54 93
	 * 退出
55 94
	 */

+ 0 - 4
src/main/java/io/renren/modules/sys/controller/SysMenuController.java

@ -122,10 +122,6 @@ public class SysMenuController extends AbstractController {
122 122
	@RequestMapping("/delete")
123 123
	@RequiresPermissions("sys:menu:delete")
124 124
	public R delete(long menuId){
125
		if(menuId <= 30){
126
			return R.error("系统菜单,不能删除");
127
		}
128
129 125
		//判断是否有子菜单或按钮
130 126
		List<SysMenuEntity> menuList = sysMenuService.queryListParentId(menuId);
131 127
		if(menuList.size() > 0){

+ 2 - 2
src/main/java/io/renren/modules/sys/service/impl/SysConfigServiceImpl.java

@ -45,12 +45,12 @@ public class SysConfigServiceImpl implements SysConfigService {
45 45
	@Override
46 46
	@Transactional
47 47
	public void deleteBatch(Long[] ids) {
48
		sysConfigDao.deleteBatch(ids);
49
50 48
		for(Long id : ids){
51 49
			SysConfigEntity config = queryObject(id);
52 50
			sysConfigRedis.delete(config.getKey());
53 51
		}
52
53
		sysConfigDao.deleteBatch(ids);
54 54
	}
55 55
56 56
	@Override

+ 1 - 1
src/main/resources/application-dev.yml

@ -8,7 +8,7 @@ spring:
8 8
                username: renren
9 9
                password: 123456
10 10
            second:  #数据源2
11
                url: jdbc:mysql://localhost:3306/bdshop?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
11
                url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
12 12
                username: renren
13 13
                password: 123456
14 14
            initial-size: 10

+ 10 - 1
src/main/resources/application.yml

@ -26,7 +26,7 @@ spring:
26 26
    redis:
27 27
        open: false  # 是否开启redis缓存  true开启   false关闭
28 28
        database: 0
29
        host: redis.open.renren.io
29
        host: localhost
30 30
        port: 16379
31 31
        password:       # 密码(默认为空)
32 32
        timeout: 6000  # 连接超时时长(毫秒)
@ -41,3 +41,12 @@ mybatis:
41 41
    mapperLocations: classpath:mapper/**/*.xml
42 42
    configLocation: classpath:mybatis.xml
43 43
44
renren:
45
    # APP模块,是通过jwt认证的,如果要使用APP模块,则需要修改【加密秘钥】
46
    jwt:
47
        # 加密秘钥
48
        secret: f4e2e52034348f86b67cde581c0f9eb5[www.renren.io]
49
        # token有效时长,7天,单位秒
50
        expire: 604800
51
        header: token
52

+ 0 - 41
src/main/resources/mapper/api/TokenDao.xml

@ -1,41 +0,0 @@
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3
4
<mapper namespace="io.renren.modules.api.dao.TokenDao">
5
6
	<select id="queryByUserId" resultType="io.renren.modules.api.entity.TokenEntity">
7
		select * from tb_token where user_id = #{value}
8
	</select>
9
10
	<select id="queryByToken" resultType="io.renren.modules.api.entity.TokenEntity">
11
		select * from tb_token where token = #{value}
12
	</select>
13
	 
14
	<insert id="save">
15
		insert into tb_token
16
		(
17
			`user_id`, 
18
			`token`, 
19
			`expire_time`, 
20
			`update_time`
21
		)
22
		values
23
		(
24
			#{userId}, 
25
			#{token}, 
26
			#{expireTime}, 
27
			#{updateTime}
28
		)
29
	</insert>
30
	 
31
	<update id="update">
32
		update tb_token 
33
		<set>
34
			<if test="token != null">`token` = #{token}, </if>
35
			<if test="expireTime != null">`expire_time` = #{expireTime}, </if>
36
			<if test="updateTime != null">`update_time` = #{updateTime}</if>
37
		</set>
38
		where user_id = #{userId}
39
	</update>
40
41
</mapper>

+ 4 - 4
src/main/resources/mapper/api/UserDao.xml

@ -1,9 +1,9 @@
1 1
<?xml version="1.0" encoding="UTF-8"?>
2 2
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 3
4
<mapper namespace="io.renren.modules.api.dao.UserDao">
4
<mapper namespace="io.renren.modules.app.dao.UserDao">
5 5
6
	<insert id="save" parameterType="io.renren.modules.api.entity.UserEntity" useGeneratedKeys="true" keyProperty="userId">
6
	<insert id="save" parameterType="io.renren.modules.app.entity.UserEntity" useGeneratedKeys="true" keyProperty="userId">
7 7
		insert into tb_user
8 8
		(
9 9
			`username`,
@ -20,11 +20,11 @@
20 20
			)
21 21
	</insert>
22 22
23
	<select id="queryObject" resultType="io.renren.modules.api.entity.UserEntity">
23
	<select id="queryObject" resultType="io.renren.modules.app.entity.UserEntity">
24 24
		select * from tb_user where user_id = #{value}
25 25
	</select>
26 26
27
	<select id="queryByMobile" resultType="io.renren.modules.api.entity.UserEntity">
27
	<select id="queryByMobile" resultType="io.renren.modules.app.entity.UserEntity">
28 28
		select * from tb_user where mobile = #{value}
29 29
	</select>
30 30

+ 1 - 1
src/main/resources/static/js/modules/sys/menu.js

@ -26,7 +26,7 @@ var vm = new Vue({
26 26
        }
27 27
    },
28 28
    methods: {
29
        getMenu: function(menuId){
29
        getMenu: function(){
30 30
            //加载菜单树
31 31
            $.get(baseURL + "sys/menu/select", function(r){
32 32
                ztree = $.fn.zTree.init($("#menuTree"), setting, r.menuList);

+ 1 - 1
src/main/resources/static/js/modules/sys/role.js

@ -84,7 +84,7 @@ var vm = new Vue({
84 84
            vm.title = "修改";
85 85
            vm.getMenuTree(roleId);
86 86
		},
87
		del: function (event) {
87
		del: function () {
88 88
			var roleIds = getSelectedRows();
89 89
			if(roleIds == null){
90 90
				return ;

+ 191 - 0
src/main/resources/static/libs/store.js

@ -0,0 +1,191 @@
1
"use strict"
2
// Module export pattern from
3
// https://github.com/umdjs/umd/blob/master/returnExports.js
4
;(function (root, factory) {
5
    if (typeof define === 'function' && define.amd) {
6
        // AMD. Register as an anonymous module.
7
        define([], factory);
8
    } else if (typeof exports === 'object') {
9
        // Node. Does not work with strict CommonJS, but
10
        // only CommonJS-like environments that support module.exports,
11
        // like Node.
12
        module.exports = factory();
13
    } else {
14
        // Browser globals (root is window)
15
        root.store = factory();
16
    }
17
}(this, function () {
18
19
    // Store.js
20
    var store = {},
21
        win = (typeof window != 'undefined' ? window : global),
22
        doc = win.document,
23
        localStorageName = 'localStorage',
24
        scriptTag = 'script',
25
        storage
26
27
    store.disabled = false
28
    store.version = '1.3.20'
29
    store.set = function(key, value) {}
30
    store.get = function(key, defaultVal) {}
31
    store.has = function(key) { return store.get(key) !== undefined }
32
    store.remove = function(key) {}
33
    store.clear = function() {}
34
    store.transact = function(key, defaultVal, transactionFn) {
35
        if (transactionFn == null) {
36
            transactionFn = defaultVal
37
            defaultVal = null
38
        }
39
        if (defaultVal == null) {
40
            defaultVal = {}
41
        }
42
        var val = store.get(key, defaultVal)
43
        transactionFn(val)
44
        store.set(key, val)
45
    }
46
    store.getAll = function() {}
47
    store.forEach = function() {}
48
49
    store.serialize = function(value) {
50
        return JSON.stringify(value)
51
    }
52
    store.deserialize = function(value) {
53
        if (typeof value != 'string') { return undefined }
54
        try { return JSON.parse(value) }
55
        catch(e) { return value || undefined }
56
    }
57
58
    // Functions to encapsulate questionable FireFox 3.6.13 behavior
59
    // when about.config::dom.storage.enabled === false
60
    // See https://github.com/marcuswestin/store.js/issues#issue/13
61
    function isLocalStorageNameSupported() {
62
        try { return (localStorageName in win && win[localStorageName]) }
63
        catch(err) { return false }
64
    }
65
66
    if (isLocalStorageNameSupported()) {
67
        storage = win[localStorageName]
68
        store.set = function(key, val) {
69
            if (val === undefined) { return store.remove(key) }
70
            storage.setItem(key, store.serialize(val))
71
            return val
72
        }
73
        store.get = function(key, defaultVal) {
74
            var val = store.deserialize(storage.getItem(key))
75
            return (val === undefined ? defaultVal : val)
76
        }
77
        store.remove = function(key) { storage.removeItem(key) }
78
        store.clear = function() { storage.clear() }
79
        store.getAll = function() {
80
            var ret = {}
81
            store.forEach(function(key, val) {
82
                ret[key] = val
83
            })
84
            return ret
85
        }
86
        store.forEach = function(callback) {
87
            for (var i=0; i<storage.length; i++) {
88
                var key = storage.key(i)
89
                callback(key, store.get(key))
90
            }
91
        }
92
    } else if (doc && doc.documentElement.addBehavior) {
93
        var storageOwner,
94
            storageContainer
95
        // Since #userData storage applies only to specific paths, we need to
96
        // somehow link our data to a specific path.  We choose /favicon.ico
97
        // as a pretty safe option, since all browsers already make a request to
98
        // this URL anyway and being a 404 will not hurt us here.  We wrap an
99
        // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
100
        // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
101
        // since the iframe access rules appear to allow direct access and
102
        // manipulation of the document element, even for a 404 page.  This
103
        // document can be used instead of the current document (which would
104
        // have been limited to the current path) to perform #userData storage.
105
        try {
106
            storageContainer = new ActiveXObject('htmlfile')
107
            storageContainer.open()
108
            storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>')
109
            storageContainer.close()
110
            storageOwner = storageContainer.w.frames[0].document
111
            storage = storageOwner.createElement('div')
112
        } catch(e) {
113
            // somehow ActiveXObject instantiation failed (perhaps some special
114
            // security settings or otherwse), fall back to per-path storage
115
            storage = doc.createElement('div')
116
            storageOwner = doc.body
117
        }
118
        var withIEStorage = function(storeFunction) {
119
            return function() {
120
                var args = Array.prototype.slice.call(arguments, 0)
121
                args.unshift(storage)
122
                // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
123
                // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
124
                storageOwner.appendChild(storage)
125
                storage.addBehavior('#default#userData')
126
                storage.load(localStorageName)
127
                var result = storeFunction.apply(store, args)
128
                storageOwner.removeChild(storage)
129
                return result
130
            }
131
        }
132
133
        // In IE7, keys cannot start with a digit or contain certain chars.
134
        // See https://github.com/marcuswestin/store.js/issues/40
135
        // See https://github.com/marcuswestin/store.js/issues/83
136
        var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g")
137
        var ieKeyFix = function(key) {
138
            return key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')
139
        }
140
        store.set = withIEStorage(function(storage, key, val) {
141
            key = ieKeyFix(key)
142
            if (val === undefined) { return store.remove(key) }
143
            storage.setAttribute(key, store.serialize(val))
144
            storage.save(localStorageName)
145
            return val
146
        })
147
        store.get = withIEStorage(function(storage, key, defaultVal) {
148
            key = ieKeyFix(key)
149
            var val = store.deserialize(storage.getAttribute(key))
150
            return (val === undefined ? defaultVal : val)
151
        })
152
        store.remove = withIEStorage(function(storage, key) {
153
            key = ieKeyFix(key)
154
            storage.removeAttribute(key)
155
            storage.save(localStorageName)
156
        })
157
        store.clear = withIEStorage(function(storage) {
158
            var attributes = storage.XMLDocument.documentElement.attributes
159
            storage.load(localStorageName)
160
            for (var i=attributes.length-1; i>=0; i--) {
161
                storage.removeAttribute(attributes[i].name)
162
            }
163
            storage.save(localStorageName)
164
        })
165
        store.getAll = function(storage) {
166
            var ret = {}
167
            store.forEach(function(key, val) {
168
                ret[key] = val
169
            })
170
            return ret
171
        }
172
        store.forEach = withIEStorage(function(storage, callback) {
173
            var attributes = storage.XMLDocument.documentElement.attributes
174
            for (var i=0, attr; attr=attributes[i]; ++i) {
175
                callback(attr.name, store.deserialize(storage.getAttribute(attr.name)))
176
            }
177
        })
178
    }
179
180
    try {
181
        var testKey = '__storejs__'
182
        store.set(testKey, testKey)
183
        if (store.get(testKey) != testKey) { store.disabled = true }
184
        store.remove(testKey)
185
    } catch(e) {
186
        store.disabled = true
187
    }
188
    store.enabled = !store.disabled
189
190
    return store
191
}));

+ 50 - 36
src/main/resources/views/login.html

@ -30,16 +30,24 @@
30 30
  <div class="login-box-body">
31 31
      <p class="login-box-msg">管理员登录</p>
32 32
      <div v-if="error" class="alert alert-danger alert-dismissible">
33
        <h4 style="margin-bottom: 0px;"><i class="fa fa-exclamation-triangle"></i> {{errorMsg}}</h4>
33
        <h4 style="margin-bottom: 0px;"><i class="fa fa-exclamation-circle"></i> {{errorMsg}}</h4>
34 34
      </div>
35 35
      <div class="form-group has-feedback">
36 36
          <input type="text" class="form-control" v-model="username" placeholder="账号">
37 37
          <span class="glyphicon glyphicon-user form-control-feedback"></span>
38 38
      </div>
39 39
      <div class="form-group has-feedback">
40
          <input type="password" class="form-control" v-model="password" @keyup.enter="login" placeholder="密码">
40
          <input type="password" class="form-control" v-model="password" placeholder="密码">
41 41
          <span class="glyphicon glyphicon-lock form-control-feedback"></span>
42 42
      </div>
43
      <div class="form-group has-feedback">
44
          <input type="text" class="form-control" v-model="captcha" @keyup.enter="login" placeholder="验证码">
45
          <span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
46
      </div>
47
      <div class="form-group has-feedback">
48
          <img alt="如果看不清楚,请单击图片刷新!" class="pointer" :src="src" @click="refreshCode">
49
          &nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:;" @click="refreshCode">点击刷新</a>
50
      </div>
43 51
44 52
      <div class="row">
45 53
        <div class="col-xs-8">
@ -65,40 +73,46 @@
65 73
<script src="libs/app.js"></script>
66 74
<script src="js/common.js"></script>
67 75
<script type="text/javascript">
68
var vm = new Vue({
69
	el:'#rrapp',
70
	data:{
71
		username: '',
72
		password: '',
73
		error: false,
74
		errorMsg: ''
75
	},
76
	beforeCreate: function(){
77
		if(self != top){
78
			top.location.href = self.location.href;
79
		}
80
	},
81
	methods: {
82
		login: function () {
83
            var data = "username="+vm.username+"&password="+vm.password;
84
			$.ajax({
85
				type: "POST",
86
			    url: baseURL + "sys/login",
87
			    data: data,
88
			    dataType: "json",
89
			    success: function(r){
90
					if(r.code == 0){//登录成功
91
                        localStorage.setItem("token", r.token);
92
                        parent.location.href ='index.html';
93
					}else{
94
						vm.error = true;
95
						vm.errorMsg = r.msg;
96
					}
97
				}
98
			});
99
		}
100
	}
101
});
76
    var vm = new Vue({
77
        el:'#rrapp',
78
        data:{
79
            username: '',
80
            password: '',
81
            captcha: '',
82
            error: false,
83
            errorMsg: '',
84
            src: 'captcha.jpg'
85
        },
86
        beforeCreate: function(){
87
            if(self != top){
88
                top.location.href = self.location.href;
89
            }
90
        },
91
        methods: {
92
            refreshCode: function(){
93
                this.src = "captcha.jpg?t=" + $.now();
94
            },
95
            login: function () {
96
                var data = "username="+vm.username+"&password="+vm.password+"&captcha="+vm.captcha;
97
                $.ajax({
98
                    type: "POST",
99
                    url: baseURL + "sys/login",
100
                    data: data,
101
                    dataType: "json",
102
                    success: function(r){
103
                        if(r.code == 0){//登录成功
104
                            localStorage.setItem("token", r.token);
105
                            parent.location.href ='index.html';
106
                        }else{
107
                            vm.error = true;
108
                            vm.errorMsg = r.msg;
109
                            vm.refreshCode();
110
                        }
111
                    }
112
                });
113
            }
114
        }
115
    });
102 116
</script>
103 117
</body>
104 118
</html>

+ 13 - 9
src/test/java/io/renren/DynamicDataSourceTest.java

@ -1,9 +1,8 @@
1 1
package io.renren;
2 2
3
import io.renren.dynamicdatasource.DataSourceContext;
4
import io.renren.dynamicdatasource.DynamicDataSource;
5
import io.renren.modules.api.entity.UserEntity;
6
import io.renren.modules.api.service.UserService;
3
4
import io.renren.datasources.DataSourceTestService;
5
import io.renren.modules.app.entity.UserEntity;
7 6
import org.apache.commons.lang.builder.ToStringBuilder;
8 7
import org.junit.Test;
9 8
import org.junit.runner.RunWith;
@ -16,16 +15,21 @@ import org.springframework.test.context.junit4.SpringRunner;
16 15
@SpringBootTest
17 16
public class DynamicDataSourceTest {
18 17
    @Autowired
19
    private UserService userService;
18
    private DataSourceTestService dataSourceTestService;
20 19
21 20
    @Test
22 21
    public void test(){
23
        UserEntity user = userService.queryObject(1L);
22
        //数据源1
23
        UserEntity user = dataSourceTestService.queryObject(1L);
24 24
        System.out.println(ToStringBuilder.reflectionToString(user));
25 25
26
        //切换数据源
27
        DynamicDataSource.setDataSource(DataSourceContext.SECOND.getName());
28
        UserEntity user2 = userService.queryObject(1L);
26
        //数据源2
27
        UserEntity user2 = dataSourceTestService.queryObject2(1L);
29 28
        System.out.println(ToStringBuilder.reflectionToString(user2));
29
30
        //数据源1
31
        UserEntity user3 = dataSourceTestService.queryObject(1L);
32
        System.out.println(ToStringBuilder.reflectionToString(user3));
30 33
    }
34
31 35
}

+ 24 - 0
src/test/java/io/renren/JwtTest.java

@ -0,0 +1,24 @@
1
package io.renren;
2
3
import io.renren.common.utils.JwtUtils;
4
import org.junit.Test;
5
import org.junit.runner.RunWith;
6
import org.springframework.beans.factory.annotation.Autowired;
7
import org.springframework.boot.test.context.SpringBootTest;
8
import org.springframework.test.context.junit4.SpringRunner;
9
10
11
@RunWith(SpringRunner.class)
12
@SpringBootTest
13
public class JwtTest {
14
    @Autowired
15
    private JwtUtils jwtUtils;
16
17
    @Test
18
    public void test() {
19
        String token = jwtUtils.generateToken(1);
20
21
        System.out.println(token);
22
    }
23
24
}