第一阶段完成

This commit is contained in:
朱秀清 2021-12-26 01:22:35 +08:00
parent 647b601582
commit 4a2a0dcbfa
86 changed files with 17772 additions and 211 deletions

1
.gitignore vendored
View File

@ -18,6 +18,7 @@ target/
*.iws
*.iml
*.ipr
*.node_modules
### NetBeans ###
/nbproject/private/

View File

@ -15,7 +15,15 @@
### TODO
#### 2021-12
- [X] 获取onedrive token (secreteId->code->token)
- [ ] 使用java 调用onedrive接口 获取文件目录信息,获取文件内容
- [ ] 使用vue 展示网盘目录信息,文件内容
- [ ] 定时任务 将指定目录网盘数据交给es,es并创建索引
- [X] 使用java 调用onedrive接口 获取文件目录信息,获取文件内容
- [X] 使用vue 展示网盘目录信息,文件内容
- [X] 增加缩略图模式
![img.png](https://gitee.com/zxqzhuzhu/imgs/raw/master/picGo/image-20211226011921711.png)
#### 2022-01
- [ ] 分页列表
- [ ] 定时任务 将指定目录网盘数据交给es,es并创建索引
- [ ] 文件的上传,删除
- [ ] md文件的修改

12
pom.xml
View File

@ -8,7 +8,7 @@
<version>2.1.16.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dnslin</groupId>
<groupId>com.zhu</groupId>
<artifactId>Onemanager-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Onemanager-java</name>
@ -32,6 +32,11 @@
</exclusion>
</exclusions>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--Hutool utils-->
<dependency>
<groupId>cn.hutool</groupId>
@ -110,6 +115,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>

View File

@ -1,8 +0,0 @@
package com.dnslin.onemanager.logic;
import com.dnslin.onemanager.pojo.Onedriveconfig;
public interface BaseMicrosoftService {
Onedriveconfig getToken(String code);
}

View File

@ -1,33 +0,0 @@
package com.dnslin.onemanager.mapper;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.dnslin.onemanager.pojo.OnedriveconfigExample;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface OnedriveconfigMapper {
int countByExample(OnedriveconfigExample example);
int deleteByExample(OnedriveconfigExample example);
int deleteByPrimaryKey(String clientid);
int insert(Onedriveconfig record);
int insertSelective(Onedriveconfig record);
List<Onedriveconfig> selectByExample(OnedriveconfigExample example);
Onedriveconfig selectByPrimaryKey(String clientid);
int updateByExampleSelective(@Param("record") Onedriveconfig record, @Param("example") OnedriveconfigExample example);
int updateByExample(@Param("record") Onedriveconfig record, @Param("example") OnedriveconfigExample example);
int updateByPrimaryKeySelective(Onedriveconfig record);
int updateByPrimaryKey(Onedriveconfig record);
}

View File

@ -1,63 +0,0 @@
package com.dnslin.onemanager.pojo;
public class Onedriveconfig {
private String clientid;
private String redirecturl;
private String clientsecret;
private String accesstoken;
private String refreshtoken;
private Long expires;
public String getClientid() {
return clientid;
}
public void setClientid(String clientid) {
this.clientid = clientid == null ? null : clientid.trim();
}
public String getRedirecturl() {
return redirecturl;
}
public void setRedirecturl(String redirecturl) {
this.redirecturl = redirecturl == null ? null : redirecturl.trim();
}
public String getClientsecret() {
return clientsecret;
}
public void setClientsecret(String clientsecret) {
this.clientsecret = clientsecret == null ? null : clientsecret.trim();
}
public String getAccesstoken() {
return accesstoken;
}
public void setAccesstoken(String accesstoken) {
this.accesstoken = accesstoken == null ? null : accesstoken.trim();
}
public String getRefreshtoken() {
return refreshtoken;
}
public void setRefreshtoken(String refreshtoken) {
this.refreshtoken = refreshtoken == null ? null : refreshtoken.trim();
}
public Long getExpires() {
return expires;
}
public void setExpires(Long expires) {
this.expires = expires;
}
}

View File

@ -1,11 +1,11 @@
package com.dnslin.onemanager;
package com.zhu.onemanager;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.dnslin.onemanager.mapper")
@MapperScan("com.zhu.onemanager.mapper")
public class OnemanagerJavaApplication {
public static void main(String[] args) {

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.config;
package com.zhu.onemanager.config;
import com.google.common.base.Predicates;

View File

@ -0,0 +1,50 @@
package com.zhu.onemanager.constant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* @author zhaojun
*/
@Configuration
public class FileConstant {
public final static String USER_HOME = System.getProperty("user.home");
public static final Character PATH_SEPARATOR_CHAR = '/';
public static final String PATH_SEPARATOR = "/";
public static final String PATH_COLON_SEPARATOR = ":/";
/**
* 系统产生的临时文件路径
*/
public static String TMP_FILE_PATH = "/.zfile/tmp2/";
/**
* 页面文档文件
*/
public static String README_FILE_NAME = "readme.md";
/**
* 密码文件
*/
public static String PASSWORD_FILE_NAME = "password.txt";
/**
* 最大支持文件大小为 ? MB 的音乐文件解析封面, 歌手等信息.
*/
public static Long AUDIO_MAX_FILE_SIZE_MB = 1L;
/**
* 最大支持文本文件大小为 ? KB 的文件内容.
*/
public static Long TEXT_MAX_FILE_SIZE_KB = 100L;
}

View File

@ -0,0 +1,20 @@
package com.zhu.onemanager.constant;
/**
* @author ggBall
* @version 1.0.0
* @ClassName ItemConstant.java
* @Description TODO
* @createTime 2021年12月25日 22:54:00
*/
public class ItemConstant {
/**
* 文件夹类型
*/
public static final String FOLDER = "folder";
/**
* 文件类型
*/
public static final String FILE = "file";
}

View File

@ -0,0 +1,29 @@
package com.zhu.onemanager.context;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
/**
* @author ggBall
* @version 1.0.0
* @ClassName OnedriveContext.java
* @Description TODO
* @createTime 2021年12月17日 16:29:00
*/
@Component
@Slf4j
public class OnedriveContext implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
}
}

View File

@ -0,0 +1,14 @@
package com.zhu.onemanager.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@RequestMapping("/")
public String index() {
return "index";
}
}

View File

@ -1,10 +1,13 @@
package com.dnslin.onemanager.controller.api;
package com.zhu.onemanager.controller.api;
import cn.hutool.core.lang.Console;
import com.dnslin.onemanager.exception.AppException;
import com.dnslin.onemanager.logic.BaseMicrosoftService;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.dnslin.onemanager.result.ResponseEnum;
import com.zhu.onemanager.exception.AppException;
import com.zhu.onemanager.logic.AuthToken;
import com.zhu.onemanager.logic.AuthUrl;
import com.zhu.onemanager.logic.BaseMicrosoftService;
import com.zhu.onemanager.pojo.OnedriveConfig;
import com.zhu.onemanager.result.ResponseEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
@ -14,19 +17,27 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@RestController
@RequestMapping("/api")
@CrossOrigin
@Slf4j
public class CallbackController {
@Autowired
private ServletContext context;
@Autowired
private BaseMicrosoftService baseMicrosoftService;
@Autowired
private AuthUrl authUrl;
@Autowired
private AuthToken authToken;
@Autowired
private OnedriveConfig onedriveConfig;
@Value("${onedrive.scope}")
private String scope;
@ -35,6 +46,13 @@ public class CallbackController {
@Value("${onedrive.clientId}")
private String clientId;
@Value("${onedrive.file.scope}")
private String fileScope;
@Value("${onedrive.file.redirectUri}")
private String fileRedirectUri;
@Value("${onedrive.file.clientId}")
private String fileClientId;
/**
*
@ -44,8 +62,8 @@ public class CallbackController {
* @author DnsLin
* @date 2021/10/27 15:35
*/
@GetMapping("/auth")
public void authCallback(HttpServletRequest request, HttpServletResponse response,String code){
@GetMapping("/file/auth")
public void authCallback(HttpServletRequest request, HttpServletResponse response,String code) throws IOException {
if (request==null){
Console.log("request为空");
throw new AppException(ResponseEnum.THE_CALLBACK_FAILED);
@ -55,6 +73,23 @@ public class CallbackController {
ServletContext servletContext = context;
servletContext.setAttribute("code",code);
servletContext.setAttribute("state",state);
authToken.getAccessToken(onedriveConfig);
response.setContentType("text/html;charset=utf-8;");
PrintWriter writer = response.getWriter();
writer.println("<h2>access_token</h2>"+
"<textarea rows=\"1\" cols=\"1000\" disabled >"+
onedriveConfig.getAccessToken() +
"</textarea>"
);
writer.println("<h2>refresh_token</h2>"+
"<textarea rows=\"1\" cols=\"1000\" disabled >"+
onedriveConfig.getRefreshToken() +
"</textarea>"
);
}
@ -75,13 +110,13 @@ public class CallbackController {
// String code = request.getParameter("code");
String state = request.getParameter("state");
Onedriveconfig token = baseMicrosoftService.getToken(code);
OnedriveConfig token = baseMicrosoftService.getOutlookToken(code);
ServletContext servletContext = context;
servletContext.setAttribute("code",code);
servletContext.setAttribute("state",state);
servletContext.setAttribute("accessToken",token.getAccesstoken());
servletContext.setAttribute("refreshToken",token.getRefreshtoken());
servletContext.setAttribute("accessToken",token.getAccessToken());
servletContext.setAttribute("refreshToken",token.getRefreshToken());
String directUrl = "redirect:https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + clientId +
"&response_type=code&redirect_uri=" + redirectUri +

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.controller.api;
package com.zhu.onemanager.controller.api;
/**
* @author: DnsLin
@ -12,19 +12,18 @@ import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.dnslin.onemanager.logic.AuthToken;
import com.dnslin.onemanager.logic.AuthUrl;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.dnslin.onemanager.result.R;
import com.dnslin.onemanager.result.ResponseEnum;
import com.zhu.onemanager.logic.AuthToken;
import com.zhu.onemanager.logic.AuthUrl;
import com.zhu.onemanager.pojo.OnedriveConfig;
import com.zhu.onemanager.result.R;
import com.zhu.onemanager.result.ResponseEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@RestController
@ -40,11 +39,13 @@ public class MicrosoftAuthController {
private AuthUrl authUrl;
@Autowired
private ServletContext context;
@Resource
private OnedriveConfig onedriveConfig;
@PostMapping("/MicrosoftLogin")
public R MicrosoftLogin(Onedriveconfig config) {
public R MicrosoftLogin(OnedriveConfig config) {
if (config != null) {
String urlAuthUrl = authUrl.getAuthUrl(config.getClientid(), config.getClientsecret());
String urlAuthUrl = authUrl.getAuthUrl(config.getClientId(), config.getClientSecret(),"");
try {
authToken.getRefreshToken(config);
} catch (IOException e) {
@ -69,4 +70,9 @@ public class MicrosoftAuthController {
return new R(ResponseEnum.SUCCESS,execute);
}
@GetMapping("/token")
public R getToken() {
return R.ok(onedriveConfig);
}
}

View File

@ -0,0 +1,52 @@
package com.zhu.onemanager.controller.onedrive;
import com.zhu.onemanager.pojo.DriveParams;
import com.zhu.onemanager.result.R;
import com.zhu.onemanager.service.OnedriveService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author ggBall
* @version 1.0.0
* @ClassName OnedriveController.java
* @Description TODO
* @createTime 2021年12月17日 13:15:00
*/
@RestController
@RequestMapping("/oneDrive")
@CrossOrigin
@Slf4j
public class OnedriveController {
@Resource
private OnedriveService onedriveService;
/**
* @Author ggball
* @Description 获取获取当前用户根路径下的文件信息
* @Date 2021/12/17
* @Param []
* @return com.dnslin.onemanager.result.R
**/
@GetMapping("/index")
public R getCurrentDriveInfo(DriveParams driveParams) {
String path = "me/drive/root/children" + driveParams.getUrl();
R r = onedriveService.getCurrentDriveInfo(path);
return r;
}
@GetMapping("/{itemId}/children")
public R children(@PathVariable("itemId") String itemId,DriveParams driveParams) {
log.info("itemId:{}",itemId);
String path = "me/drive/items/%s/children"+driveParams.getUrl();
String formatPath = String.format(path,itemId);
R r = onedriveService.children(formatPath);
return r;
}
}

View File

@ -1,8 +1,8 @@
package com.dnslin.onemanager.exception;
package com.zhu.onemanager.exception;
import com.dnslin.onemanager.result.ResponseEnum;
import com.zhu.onemanager.result.ResponseEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@ -1,10 +1,10 @@
package com.dnslin.onemanager.exception;
package com.zhu.onemanager.exception;
import com.dnslin.onemanager.result.R;
import com.dnslin.onemanager.result.ResponseEnum;
import com.zhu.onemanager.result.R;
import com.zhu.onemanager.result.ResponseEnum;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

View File

@ -1,6 +1,6 @@
package com.dnslin.onemanager.logic;
package com.zhu.onemanager.logic;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.zhu.onemanager.pojo.OnedriveConfig;
import java.io.IOException;
@ -21,7 +21,7 @@ public interface AuthToken {
* @author DnsLin
* @date 2021/10/31 18:40
*/
void getAccessToken(Onedriveconfig config) throws IOException;
void getAccessToken(OnedriveConfig config) throws IOException;
/**
*
@ -31,5 +31,5 @@ public interface AuthToken {
* @author DnsLin
* @date 2021/10/31 18:40
*/
void getRefreshToken(Onedriveconfig config) throws IOException;
void getRefreshToken(OnedriveConfig config) throws IOException;
}

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.logic;
package com.zhu.onemanager.logic;
public interface AuthUrl {
@ -8,7 +8,8 @@ public interface AuthUrl {
* @date 2021/10/25
* @param clientId 客户端ID
* @param redirectUri 回调URL
* @param scope 权限
* @return AuthUrl 重定向url
*/
String getAuthUrl(String clientId, String redirectUri);
String getAuthUrl(String clientId, String redirectUri,String scope);
}

View File

@ -0,0 +1,9 @@
package com.zhu.onemanager.logic;
import com.zhu.onemanager.pojo.OnedriveConfig;
public interface BaseMicrosoftService {
OnedriveConfig getOutlookToken(String code);
OnedriveConfig getFileToken(String code);
}

View File

@ -1,23 +1,20 @@
package com.dnslin.onemanager.logic.impl;
package com.zhu.onemanager.logic.impl;
import cn.hutool.http.GlobalHeaders;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.dnslin.onemanager.exception.AppException;
import com.dnslin.onemanager.logic.AuthToken;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.dnslin.onemanager.result.ResponseEnum;
import com.dnslin.onemanager.service.SaveConfig;
import com.zhu.onemanager.exception.AppException;
import com.zhu.onemanager.logic.AuthToken;
import com.zhu.onemanager.pojo.OnedriveConfig;
import com.zhu.onemanager.result.ResponseEnum;
import com.zhu.onemanager.service.SaveConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ -47,36 +44,36 @@ public class AuthTokenImpl implements AuthToken {
}
@Override
public void getAccessToken(Onedriveconfig config) throws IOException {
public void getAccessToken(OnedriveConfig config) throws IOException {
String code = (String) context.getAttribute("code");
if (code == null || code.isEmpty()) {
throw new AppException(ResponseEnum.AUTH_CODE_ISNULL);
}
Map<String, Object> param = new HashMap<String, Object>();
param.put("client_id", config.getClientid());
param.put("scope", "files.readwrite.all files.readwrite offline_access");
param.put("client_id", config.getClientId());
param.put("scope", config.getScope());
param.put("code", code);
param.put("redirect_uri", config.getRedirecturl());
param.put("redirect_uri", config.getRedirectUri());
param.put("grant_type", "authorization_code");
param.put("client_secret", config.getRedirecturl());
param.put("client_secret", config.getClientSecret());
String res = HttpUtil.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", param,3000);
extracted(res, config);
}
@Override
public void getRefreshToken(Onedriveconfig config) throws IOException {
public void getRefreshToken(OnedriveConfig config) throws IOException {
if ((context.getAttribute("refresh_token") == null && context.getAttribute("refresh_token").toString().isEmpty()) || (context.getAttribute("access_token") == null && context.getAttribute("access_token").toString().isEmpty())) {
log.info("Refresh_token:==>" + context.getAttribute("refresh_token"));
log.info("Access_token:==>" + context.getAttribute("access_token"));
throw new AppException(ResponseEnum.Token_invalid);
}
Map<String, Object> param = new HashMap<String, Object>();
param.put("client_id", config.getClientid());
param.put("client_id", config.getClientId());
param.put("scope", "files.readwrite.all files.readwrite offline_access");
param.put("refresh_token", context.getAttribute("refresh_token").toString());
param.put("redirect_uri", config.getRedirecturl());
param.put("redirect_uri", config.getRedirectUri());
param.put("grant_type", "refresh_token");
param.put("client_secret", config.getRedirecturl());
param.put("client_secret", config.getClientSecret());
String res = HttpUtil.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", param,3000);
extracted(res, config);
}
@ -90,7 +87,7 @@ public class AuthTokenImpl implements AuthToken {
* @author DnsLin
* @date 2021/10/29 23:55
*/
private void extracted(String accessJson, Onedriveconfig config) {
private void extracted(String accessJson, OnedriveConfig config) {
if (accessJson == null || accessJson.isEmpty()) {
throw new AppException(ResponseEnum.THE_RESULT_SET_IS_EMPTY);
}
@ -99,9 +96,13 @@ public class AuthTokenImpl implements AuthToken {
String refresh_token = JSONObject.parseObject(accessJson).getString("refresh_token");
log.info("Access_token:==>" + access_token);
log.info("Refresh_token:==>" + refresh_token);
config.setAccesstoken(access_token);
config.setRefreshtoken(refresh_token);
config.setAccessToken(access_token);
config.setRefreshToken(refresh_token);
context.setAttribute("OnedriveConfig", config);
saveConfig.saveOnedriveConfig(config);
// 将token 存入请求头
GlobalHeaders.INSTANCE.header("Authorization","bearer "+access_token);
//saveConfig.saveOnedriveConfig(config);
}
}

View File

@ -1,7 +1,7 @@
package com.dnslin.onemanager.logic.impl;
package com.zhu.onemanager.logic.impl;
import cn.hutool.core.util.RandomUtil;
import com.dnslin.onemanager.logic.AuthUrl;
import com.zhu.onemanager.logic.AuthUrl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -19,14 +19,14 @@ public class AuthUrlImpl implements AuthUrl {
* @return AuthUrl 重定向url
*/
@Override
public String getAuthUrl(String clientId, String redirectUri) {
public String getAuthUrl(String clientId, String redirectUri,String scope) {
String state = RandomUtil.randomString(10);
return String.format("https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" +
"client_id=%s" +
"&response_type=code" +
"&redirect_uri=%s" +
"&response_mode=query" +
"&scope=files.readwrite.all files.readwrite offline_access" +
"&state=%s", clientId, redirectUri, state);
"&scope=%s" + // files.readwrite.all files.readwrite offline_access
"&state=%s", clientId, redirectUri, scope,state);
}
}

View File

@ -1,11 +1,11 @@
package com.dnslin.onemanager.logic.impl;
package com.zhu.onemanager.logic.impl;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.dnslin.onemanager.logic.BaseMicrosoftService;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.zhu.onemanager.logic.BaseMicrosoftService;
import com.zhu.onemanager.pojo.OnedriveConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@ -32,14 +32,24 @@ public class BaseMicrosoftServiceImpl implements BaseMicrosoftService {
private String authenticateEndPoint;
@Value("${onedrive.file.scope}")
private String fileScope;
@Value("${onedrive.file.redirectUri}")
private String fileRedirectUri;
@Value("${onedrive.file.clientId}")
private String fileClientId;
@Value("${onedrive.file.clientSecret}")
private String fileClientSecret;
protected static final String AUTHENTICATE_URL = "https://{authenticateEndPoint}/common/oauth2/v2.0/token";
@Override
public Onedriveconfig getToken(String code) {
String param = "client_id=" + clientId +
public OnedriveConfig getOutlookToken(String code) {
String param = "client_id=" + fileClientId +
"&redirect_uri=" + redirectUri +
"&client_secret=" + clientSecret +
"&code=" + code +
@ -51,7 +61,24 @@ public class BaseMicrosoftServiceImpl implements BaseMicrosoftService {
post.body(param, "application/x-www-form-urlencoded");
HttpResponse response = post.execute();
return JSONObject.parseObject(response.body(), Onedriveconfig.class);
return JSONObject.parseObject(response.body(), OnedriveConfig.class);
}
@Override
public OnedriveConfig getFileToken(String code) {
String param = "client_id=" + fileClientId +
"&redirect_uri=" + fileRedirectUri +
"&client_secret=" + fileClientSecret +
"&code=" + code +
"&scope=" + fileScope +
"&grant_type=authorization_code";
String fullAuthenticateUrl = AUTHENTICATE_URL.replace("{authenticateEndPoint}", authenticateEndPoint);
HttpRequest post = HttpUtil.createPost(fullAuthenticateUrl);
post.body(param, "application/x-www-form-urlencoded");
HttpResponse response = post.execute();
return JSONObject.parseObject(response.body(), OnedriveConfig.class);
}
private String getScope() {

View File

@ -0,0 +1,33 @@
package com.zhu.onemanager.mapper;
import com.zhu.onemanager.pojo.OnedriveConfig;
import com.zhu.onemanager.pojo.OnedriveconfigExample;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface OnedriveconfigMapper {
int countByExample(OnedriveconfigExample example);
int deleteByExample(OnedriveconfigExample example);
int deleteByPrimaryKey(String clientid);
int insert(OnedriveConfig record);
int insertSelective(OnedriveConfig record);
List<OnedriveConfig> selectByExample(OnedriveconfigExample example);
OnedriveConfig selectByPrimaryKey(String clientid);
int updateByExampleSelective(@Param("record") OnedriveConfig record, @Param("example") OnedriveconfigExample example);
int updateByExample(@Param("record") OnedriveConfig record, @Param("example") OnedriveconfigExample example);
int updateByPrimaryKeySelective(OnedriveConfig record);
int updateByPrimaryKey(OnedriveConfig record);
}

View File

@ -0,0 +1,123 @@
package com.zhu.onemanager.pojo;
import cn.hutool.core.lang.Dict;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.zhu.onemanager.constant.ItemConstant;
import lombok.Data;
import java.util.Date;
/**
* @author ggBall
* @version 1.0.0
* @ClassName DriveItem.java
* @Description TODO
* @createTime 2021年12月17日 17:52:00
*/
@Data
public class DriveItem {
/**
* 驱动器唯一标识符只读
*/
private String id;
/**
* 上次修改项目的日期和时间只读
*/
private Date lastModifiedDateTime;
/**
* 上次修改项目的日期和时间只读
*/
private Date createdDateTime;
/**
* 上次修改项目的用户设备和应用程序的标识只读
*/
private JSONObject lastModifiedBy;
/**
* 上项目名称读写
*/
private String name;
/**
* 项目大小以字节为单位只读
*/
private Long size;
/**
* 父信息如果此项具有父级读写
*/
private JSONObject parentReference;
/**
* 文件信息
*/
private File file;
/**
* 文件夹信息
*/
private Folder folder;
/**
* item类型: {@link com.zhu.onemanager.constant.ItemConstant}
*/
// private String itemType;
/**
*下载url
*/
private String downloadUrl;
/**
*缩略图列表
*/
private JSONArray thumbnails;
/**
*缩略图
*/
public String getThumbnail() {
if (null != thumbnails && thumbnails.size() > 0) {
JSONObject thumbnailJson = (JSONObject)thumbnails.get(0);
JSONObject mediumImg = (JSONObject)thumbnailJson.get("medium");
return mediumImg.getString("url");
}
return null;
}
@JSONField(name = "@microsoft.graph.downloadUrl")
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
/**
* 获取当前path
* @return
*/
public String getPath() {
return parentReference.getString("path");
}
/**
* item类型: {@link com.zhu.onemanager.constant.ItemConstant}
*/
public String getItemType() {
if (null != file) {
return ItemConstant.FILE;
}
if (null != folder) {
return ItemConstant.FOLDER;
}
return null;
}
}

View File

@ -0,0 +1,29 @@
package com.zhu.onemanager.pojo;
import lombok.Data;
/**
* @author ggBall
* @version 1.0.0
* @ClassName DriveParams.java
* @Description 传参
* @createTime 2021年12月25日 23:10:00
*/
@Data
public class DriveParams {
/**
* 是否展示缩略图
*/
private boolean thumbnail;
public String getUrl() {
StringBuilder params = new StringBuilder();
params.append("?$expand=");
if (thumbnail) {
params.append("thumbnails");
}
return params.toString();
}
}

View File

@ -0,0 +1,32 @@
package com.zhu.onemanager.pojo;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
/**
* @author ggBall
* @version 1.0.0
* @ClassName File.java
* @Description TODO
* @createTime 2021年12月20日 14:22:00
*/
@Data
public class File implements Serializable {
/**
* 文件的 MIME 类型这由服务器上的逻辑决定不能是在上载文件时提供的值只读
*/
private String mimeType;
/**
* 文件的 MIME 类型这由服务器上的逻辑决定不能是在上载文件时提供的值只读
*/
private JSONObject hashes;
/**
* 文件的 MIME 类型这由服务器上的逻辑决定不能是在上载文件时提供的值只读
*/
private Boolean processingMetadata;
}

View File

@ -0,0 +1,27 @@
package com.zhu.onemanager.pojo;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.io.Serializable;
/**
* @author ggBall
* @version 1.0.0
* @ClassName Folder.java
* @Description TODO
* @createTime 2021年12月20日 14:25:00
*/
@Data
public class Folder implements Serializable {
/**
*此容器包含的直接子项数量
*/
private Integer childCount;
/**
* 用于定义文件夹的推荐视图的属性集合
*/
private JSONObject view;
}

View File

@ -0,0 +1,28 @@
package com.zhu.onemanager.pojo;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "onedrive.file")
public class OnedriveConfig {
private String clientId;
private String redirectUri;
private String clientSecret;
private String accessToken;
private String refreshToken;
private Long expires;
private String scope;
}

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.pojo;
package com.zhu.onemanager.pojo;
import java.util.ArrayList;
import java.util.List;

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.result;
package com.zhu.onemanager.result;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -10,15 +10,20 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@Builder
// 创建统一的返回格式
public class R<T> {
public class R {
private String code;
private String message;
private T data;
private Object data;
public R(ResponseEnum responseEnum, T data) {
public R(ResponseEnum responseEnum, Object data) {
this.code = responseEnum.getCode();
this.message = responseEnum.getMessage();
this.data = data;
}
public static R ok(Object data) {
return new R(ResponseEnum.SUCCESS,data);
}
}

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.result;
package com.zhu.onemanager.result;
public enum ResponseEnum {

View File

@ -0,0 +1,18 @@
package com.zhu.onemanager.service;
import com.alibaba.fastjson.JSONArray;
import com.zhu.onemanager.pojo.DriveItem;
import java.util.Map;
/**
* @author ggBall
* @version 1.0.0
* @ClassName MapToDriveItem.java
* @Description TODO
* @createTime 2021年12月25日 22:44:00
*/
public interface MapToItem {
DriveItem toDriveItem(JSONArray array);
}

View File

@ -0,0 +1,25 @@
package com.zhu.onemanager.service;
import com.zhu.onemanager.result.R;
public interface OnedriveService {
/**
* @Author ggball
* @Description 获取获取当前用户根路径下的文件信息
* @Date 2021/12/17
* @Param []
* @return com.dnslin.onemanager.result.R
**/
R getCurrentDriveInfo(String path);
/**
* @Author ggball
* @Description 返回该项目下的子集
* @Date 2021/12/20
* @Param [path]
* @return com.zhu.onemanager.result.R
**/
R children(String path);
}

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.service;/**
package com.zhu.onemanager.service;/**
* @author: DnsLin
* @Title: SaveConfig
* @ProjectName: Onemanager-java
@ -6,7 +6,7 @@ package com.dnslin.onemanager.service;/**
* @date: 2021/10/31 18:26
*/
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.zhu.onemanager.pojo.OnedriveConfig;
/**
* @author: DnsLin
@ -24,5 +24,5 @@ public interface SaveConfig {
* @author DnsLin
* @date 2021/10/31 18:27
*/
void saveOnedriveConfig(Onedriveconfig config);
void saveOnedriveConfig(OnedriveConfig config);
}

View File

@ -0,0 +1,48 @@
package com.zhu.onemanager.service.impl;
import cn.hutool.core.lang.Dict;
import com.alibaba.fastjson.JSONArray;
import com.zhu.onemanager.constant.ItemConstant;
import com.zhu.onemanager.pojo.DriveItem;
import com.zhu.onemanager.service.MapToItem;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author ggBall
* @version 1.0.0
* @ClassName MapToDriveItemImpl.java
* @Description TODO
* @createTime 2021年12月25日 22:44:00
*/
public class MapToDriveItemImpl implements MapToItem {
@Override
public DriveItem toDriveItem(JSONArray array) {
List<DriveItem> driveItems = new LinkedList<>();
for (Object o : array) {
DriveItem driveItem = new DriveItem();
Dict itemDict = Dict.of(o);
driveItem.setCreatedDateTime(itemDict.getDate("createdDateTime"));
driveItem.setLastModifiedDateTime(itemDict.getDate("lastModifiedDateTime"));
driveItem.setDownloadUrl(itemDict.getStr("downloadUrl"));
driveItem.setId(itemDict.getStr("id"));
driveItem.setName(itemDict.getStr("name"));
// 判断item类型
Object file = itemDict.get("file");
Object folder = itemDict.get("folder");
// if (null != file) {
// driveItem.setItemType(ItemConstant.FILE);
// }
// if (null != folder) {
// driveItem.setItemType(ItemConstant.FOLDER);
// }
itemDict.set("createdDateTime",itemDict.getStr("createdDateTime"));
itemDict.set("createdDateTime",itemDict.getStr("createdDateTime"));
itemDict.set("createdDateTime",itemDict.getStr("createdDateTime"));
}
return null;
}
}

View File

@ -0,0 +1,51 @@
package com.zhu.onemanager.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.zhu.onemanager.constant.FileConstant;
import com.zhu.onemanager.pojo.DriveItem;
import com.zhu.onemanager.result.R;
import com.zhu.onemanager.service.OnedriveService;
import com.zhu.onemanager.utlis.GHttpUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @author ggBall
* @version 1.0.0
* @ClassName OnedriveServiceImpl.java
* @Description TODO
* @createTime 2021年12月17日 13:21:00
*/
@Service
public class OnedriveServiceImpl implements OnedriveService {
@Value("${microsoft-graph.root-url}")
String rootUrl;
/**
* @Author ggball
* @Description 获取获取当前用户根路径下的文件信息
* @Date 2021/12/17
* @Param []
* @return com.dnslin.onemanager.result.R
**/
@Override
public R getCurrentDriveInfo(String path) {
Map map = GHttpUtil.getMap(rootUrl + FileConstant.PATH_SEPARATOR + path);
JSONArray value = (JSONArray)map.get("value");
List<DriveItem> driveItemList = value.toJavaList(DriveItem.class);
return R.ok(driveItemList);
}
@Override
public R children(String path) {
Map map = GHttpUtil.getMap(rootUrl + FileConstant.PATH_SEPARATOR + path);
JSONArray value = (JSONArray)map.get("value");
List<DriveItem> driveItemList = value.toJavaList(DriveItem.class);
return R.ok(driveItemList);
}
}

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.service.impl;/**
package com.zhu.onemanager.service.impl;/**
* @author: DnsLin
* @Title: SaveConfigImpl
* @ProjectName: Onemanager-java
@ -6,11 +6,11 @@ package com.dnslin.onemanager.service.impl;/**
* @date: 2021/10/31 18:28
*/
import com.dnslin.onemanager.exception.AppException;
import com.dnslin.onemanager.mapper.OnedriveconfigMapper;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.dnslin.onemanager.result.ResponseEnum;
import com.dnslin.onemanager.service.SaveConfig;
import com.zhu.onemanager.exception.AppException;
import com.zhu.onemanager.mapper.OnedriveconfigMapper;
import com.zhu.onemanager.pojo.OnedriveConfig;
import com.zhu.onemanager.result.ResponseEnum;
import com.zhu.onemanager.service.SaveConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -23,12 +23,12 @@ public class SaveConfigImpl implements SaveConfig {
@Override
@Transactional
public void saveOnedriveConfig(Onedriveconfig config) {
public void saveOnedriveConfig(OnedriveConfig config) {
if (config == null) {
throw new AppException(ResponseEnum.OBJECT_IS_EMPTY);
}
// 当clientId存在时候 为更新数据 不存在就插入
Onedriveconfig onedriveconfig = onedriveconfigMapper.selectByPrimaryKey(config.getClientid());
OnedriveConfig onedriveconfig = onedriveconfigMapper.selectByPrimaryKey(config.getClientId());
if (onedriveconfig == null) {
int state = onedriveconfigMapper.insertSelective(config);
if (state < 1) {

View File

@ -1,14 +1,12 @@
package com.dnslin.onemanager.task;
package com.zhu.onemanager.task;
import com.dnslin.onemanager.logic.AuthToken;
import com.dnslin.onemanager.pojo.Onedriveconfig;
import com.zhu.onemanager.logic.AuthToken;
import com.zhu.onemanager.pojo.OnedriveConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
/**
@ -27,9 +25,9 @@ public class TimeToRefresh {
@Autowired
private ServletContext context;
@Scheduled(fixedRate = 1000 * 60 * 29, initialDelay = 1000 * 290)
@Scheduled(fixedRate = 1000 * 60 * 1, initialDelay = 1000 * 1)
public void runGetToken() throws IOException {
Onedriveconfig config = (Onedriveconfig) context.getAttribute("OnedriveConfig");
OnedriveConfig config = (OnedriveConfig) context.getAttribute("OnedriveConfig");
authTokenImpl.getRefreshToken(config);
}

View File

@ -0,0 +1,13 @@
package com.zhu.onemanager.utlis;
/**
* @author ggBall
* @version 1.0.0
* @ClassName FileUtils.java
* @Description TODO
* @createTime 2021年12月17日 17:51:00
*/
public class FileUtils {
}

View File

@ -0,0 +1,28 @@
package com.zhu.onemanager.utlis;
import cn.hutool.http.GlobalHeaders;
import cn.hutool.http.HttpGlobalConfig;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import java.util.Map;
/**
* @author ggBall
* @version 1.0.0
* @ClassName GHttpUtil.java
* @Description TODO
* @createTime 2021年12月17日 17:02:00
*/
public class GHttpUtil extends HttpUtil {
public static Map getMap(String urlString) {
String res = get(urlString, HttpGlobalConfig.getTimeout());
return JSONObject.parseObject(res, Map.class);
}
public static void putHeaders(String name,String value) {
GlobalHeaders instance = GlobalHeaders.INSTANCE;
instance.header(name,value);
}
}

View File

@ -12,6 +12,8 @@ spring:
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
validation-query: SELECT 1 FROM DUAL
resources:
static-locations: classpath:/
logging:
level:
root: info
@ -25,3 +27,12 @@ onedrive:
redirectUri: http://localhost:8081/api/outlook
clientId: 0d5e84db-18cf-4ab7-bc67-4af2dc9bce6b
authenticateEndPoint: login.microsoftonline.com
# 文件应用密钥信息
file:
clientSecret: wfy7Q~0R2MmSF6Zl3YRTcXxkGF0L8XOb_CL7k
scope: offline_access Files.Read Files.ReadWrite Files.Read.All Files.ReadWrite.All
redirectUri: http://localhost:8081/api/file/auth
clientId: 526c05e9-5e68-4178-aa62-43f70ba4ae96
authenticateEndPoint: login.microsoftonline.com
microsoft-graph:
root-url: https://graph.microsoft.com/v1.0

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.dnslin.onemanager.mapper.OnedriveconfigMapper" >
<resultMap id="BaseResultMap" type="com.dnslin.onemanager.pojo.Onedriveconfig" >
<resultMap id="BaseResultMap" type="com.zhu.onemanager.pojo.OnedriveConfig" >
<id column="clientId" property="clientid" jdbcType="VARCHAR" />
<result column="redirectUrl" property="redirecturl" jdbcType="VARCHAR" />
<result column="clientSecret" property="clientsecret" jdbcType="VARCHAR" />
@ -70,7 +70,7 @@
<sql id="Base_Column_List" >
clientId, redirectUrl, clientSecret, accessToken, refreshToken, expires
</sql>
<select id="selectByExample" resultMap="BaseResultMap" parameterType="com.dnslin.onemanager.pojo.OnedriveconfigExample" >
<select id="selectByExample" resultMap="BaseResultMap" parameterType="com.zhu.onemanager.pojo.OnedriveconfigExample" >
select
<if test="distinct" >
distinct
@ -94,13 +94,13 @@
delete from onedriveconfig
where clientId = #{clientid,jdbcType=VARCHAR}
</delete>
<delete id="deleteByExample" parameterType="com.dnslin.onemanager.pojo.OnedriveconfigExample" >
<delete id="deleteByExample" parameterType="com.zhu.onemanager.pojo.OnedriveconfigExample" >
delete from onedriveconfig
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="com.dnslin.onemanager.pojo.Onedriveconfig" >
<insert id="insert" parameterType="com.zhu.onemanager.pojo.OnedriveConfig" >
insert into onedriveconfig (clientId, redirectUrl, clientSecret,
accessToken, refreshToken, expires
)
@ -108,7 +108,7 @@
#{accesstoken,jdbcType=VARCHAR}, #{refreshtoken,jdbcType=VARCHAR}, #{expires,jdbcType=BIGINT}
)
</insert>
<insert id="insertSelective" parameterType="com.dnslin.onemanager.pojo.Onedriveconfig" >
<insert id="insertSelective" parameterType="com.zhu.onemanager.pojo.OnedriveConfig" >
insert into onedriveconfig
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="clientid != null" >
@ -151,7 +151,7 @@
</if>
</trim>
</insert>
<select id="countByExample" parameterType="com.dnslin.onemanager.pojo.OnedriveconfigExample" resultType="java.lang.Integer" >
<select id="countByExample" parameterType="com.zhu.onemanager.pojo.OnedriveconfigExample" resultType="java.lang.Integer" >
select count(*) from onedriveconfig
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
@ -195,7 +195,7 @@
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="com.dnslin.onemanager.pojo.Onedriveconfig" >
<update id="updateByPrimaryKeySelective" parameterType="com.zhu.onemanager.pojo.OnedriveConfig" >
update onedriveconfig
<set >
<if test="redirecturl != null" >
@ -216,7 +216,7 @@
</set>
where clientId = #{clientid,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="com.dnslin.onemanager.pojo.Onedriveconfig" >
<update id="updateByPrimaryKey" parameterType="com.zhu.onemanager.pojo.OnedriveConfig" >
update onedriveconfig
set redirectUrl = #{redirecturl,jdbcType=VARCHAR},
clientSecret = #{clientsecret,jdbcType=VARCHAR},

View File

@ -0,0 +1,18 @@
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]
}
}
}

View File

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

View File

@ -0,0 +1,5 @@
/build/
/config/
/dist/
/*.js
/test/unit/coverage/

View File

@ -0,0 +1,29 @@
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: true,
},
extends: [
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
'plugin:vue/essential',
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
'standard'
],
// required to lint *.vue files
plugins: [
'vue'
],
// add your custom rules here
rules: {
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}

17
src/main/resources/webapp/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
/test/unit/coverage/
/test/e2e/reports/
selenium-debug.log
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln

View File

@ -0,0 +1,10 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}

View File

@ -0,0 +1,30 @@
# webapp
> A Vue.js project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
# run unit tests
npm run unit
# run e2e tests
npm run e2e
# run all tests
npm test
```
For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).

View File

@ -0,0 +1,41 @@
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})

View File

@ -0,0 +1,54 @@
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,101 @@
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}

View File

@ -0,0 +1,22 @@
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}

View File

@ -0,0 +1,92 @@
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}

View File

@ -0,0 +1,95 @@
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})

View File

@ -0,0 +1,149 @@
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig

View File

@ -0,0 +1,7 @@
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})

View File

@ -0,0 +1,76 @@
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: false,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../../templates/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../../'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}

View File

@ -0,0 +1,4 @@
'use strict'
module.exports = {
NODE_ENV: '"production"'
}

View File

@ -0,0 +1,7 @@
'use strict'
const merge = require('webpack-merge')
const devEnv = require('./dev.env')
module.exports = merge(devEnv, {
NODE_ENV: '"testing"'
})

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>webapp</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

15417
src/main/resources/webapp/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
{
"name": "webapp",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "a1667834841 <1667834841@qq.com>",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"unit": "jest --config test/unit/jest.conf.js --coverage",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit test/e2e/specs",
"build": "node build/build.js"
},
"dependencies": {
"axios": "^0.24.0",
"element-ui": "^2.0.0-rc.1",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"file-loader": "^1.1.11",
"sass-loader": "^7.1.0",
"css-loader": "^0.28.11"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-jest": "^21.0.2",
"babel-loader": "^7.1.1",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^2.0.1",
"chromedriver": "^2.27.2",
"copy-webpack-plugin": "^4.0.1",
"cross-spawn": "^5.0.1",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.0.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"jest": "^22.0.4",
"jest-serializer-vue": "^0.3.0",
"nightwatch": "^0.9.12",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"selenium-server": "^3.0.1",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-jest": "^1.0.2",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

View File

@ -0,0 +1,23 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 0px;
height: 100%;
}
</style>

View File

@ -0,0 +1,16 @@
import axios from 'axios'
const baseUrl = 'http://localhost:8080/'
export default function index () {
return axios
.get(baseUrl + 'oneDrive/index')
.then(function (response) {
console.log(response.data.data)
return response.data.data
})
.catch(function (error) {
console.log(error)
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,15 @@
<template>
<div>
<input type="text" placeholder="写点什么吧">
</div>
</template>
<script>
export default {
name: 'Demo'
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,13 @@
<template>
</template>
<script>
export default {
name: 'Main'
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,183 @@
<template>
<div id="table">
<el-row :gutter="20">
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
<el-col :span="6">
<el-switch
v-model="isThumbnail"
active-text="缩略图模式"
inactive-text="列表模式">
</el-switch>
</el-col>
</el-row>
<el-table
style="width: 100%"
:data="fileList"
>
<el-table-column
prop="name"
label="文件名"
>
</el-table-column>
<el-table-column
prop="image"
label="图片"
width="250"
v-if="isThumbnail"
>
<template slot-scope="scope">
<img :src="scope.row.thumbnail" min-width="70" height="70" />
</template>
</el-table-column>
<el-table-column
prop="lastModifiedDateTime"
label="修改时间"
width="180"
:formatter="timeFormat"
></el-table-column>
<el-table-column
prop="size"
label="大小"
width="180"
:formatter="bytesToSize"
>
</el-table-column>
<el-table-column
label="操作"
width="180"
>
<template slot-scope="scope">
<el-link :href="scope.row.downloadUrl" :underline="false" style="margin-left:15px">
<el-button
size="mini"
>{{scope.row.itemType == 'file' ? '下载' : '查看'}}</el-button>
</el-link>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import axios from 'axios'
const baseUrl = 'http://localhost:8081/'
export default {
name: 'Table',
created () {
this.index()
},
data () {
return {
fileList: [],
isThumbnail: false,
}
},
watch: {
//
isThumbnail: 'watchThumbnail'
},
methods: {
watchThumbnail(curVal,oldVal) {
// if false -> true reIndex
if (oldVal == false && curVal == true) {
this.index();
}
// console.log(curVal,oldVal);
},
handleDownload (index, row) {
console.log(index, row)
},
index () {
const that = this
return axios
.get(baseUrl + 'oneDrive/index',{
params: {
thumbnail: that.isThumbnail
}
})
.then(response => {
console.log(response.data.data)
that.fileList = response.data.data
return response.data.data
})
.catch(function (error) {
console.log(error)
})
},
//
bytesToSize (item) {
var bytes = item.size
if (bytes === 0) return '0 B'
var k = 1000, // or 1024
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k))
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]
},
//
timeFormat (item) {
var d = new Date(item.lastModifiedDateTime.substr(0, 19))// substr(0, 19)iosNAN
var year = d.getFullYear() //
var month = d.getMonth() + 1 //
var day = d.getDate() //
var hh = d.getHours() //
var mm = d.getMinutes() //
var ss = d.getSeconds() //
var clock = year + '-'
if (month < 10) { clock += '0' }
clock += month + '-'
if (day < 10) { clock += '0' }
clock += day + ' '
if (hh < 10) { clock += '0' }
clock += hh + ':'
if (mm < 10) clock += '0'
clock += mm + ':'
if (ss < 10) clock += '0'
clock += ss
return (clock)
}
}
}
</script>
<style scoped>
.el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #ffffff;
}
.bg-purple {
background: #ffffff;
}
.bg-purple-light {
background: #ffffff;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<div class="navbar">
<el-row>
<el-col :span="24">
<div class="grid-content bg-purple-dark">
<el-header>
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1"><a :href="tokenUrl" target="_blank" style="text-decoration: none;" >授权</a></el-menu-item>
<el-menu-item index="2">网盘</el-menu-item>
<!-- <el-menu-item index="3" disabled>消息中心</el-menu-item>-->
</el-menu>
</el-header>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: 'navbar',
data () {
return {
msg: 'Welcome to Your Vue.js App',
activeIndex: '1',
activeIndex2: '0',
tokenUrl: 'https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=526c05e9-5e68-4178-aa62-43f70ba4ae96&redirect_uri=http://localhost:8081/api/file/auth'
}
},
methods: {
handleSelect (key, keyPath) {
console.log(key, keyPath)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
.navbar{
width: 100%;
}
</style>

View File

@ -0,0 +1,18 @@
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})

View File

@ -0,0 +1,21 @@
import Vue from 'vue'
import Router from 'vue-router'
import Layout from '@/views/Layout'
import Table from '@/components/Table'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Layout',
component: Layout
},
{
path: '/table',
name: 'Table',
component: Table
},
]
})

View File

@ -0,0 +1,46 @@
<template>
<div id="layout">
<el-container>
<el-header>
<navbar/>
</el-header>
<el-main>
<Table/>
</el-main>
<el-footer>Footer</el-footer>
</el-container>
</div>
</template>
<script>
import navbar from '../components/navbar'
import Table from '../components/Table'
export default {
name: 'Layout',
components: {
navbar,
Table
},
methods: {
handleDownload (index, row) {
console.log(index, row)
}
// fetchData() {
// index().then((response) => {
// this.list = response.data.items;
// debugger;
// });
// },
}
}
</script>
<style scoped>
.el-header {
padding: 0 0px;
}
</style>

View File

@ -0,0 +1,27 @@
// A custom Nightwatch assertion.
// The assertion name is the filename.
// Example usage:
//
// browser.assert.elementCount(selector, count)
//
// For more information on custom assertions see:
// http://nightwatchjs.org/guide#writing-custom-assertions
exports.assertion = function (selector, count) {
this.message = 'Testing if element <' + selector + '> has count: ' + count
this.expected = count
this.pass = function (val) {
return val === this.expected
}
this.value = function (res) {
return res.value
}
this.command = function (cb) {
var self = this
return this.api.execute(function (selector) {
return document.querySelectorAll(selector).length
}, [selector], function (res) {
cb.call(self, res)
})
}
}

View File

@ -0,0 +1,46 @@
require('babel-register')
var config = require('../../config')
// http://nightwatchjs.org/gettingstarted#settings-file
module.exports = {
src_folders: ['test/e2e/specs'],
output_folder: 'test/e2e/reports',
custom_assertions_path: ['test/e2e/custom-assertions'],
selenium: {
start_process: true,
server_path: require('selenium-server').path,
host: '127.0.0.1',
port: 4444,
cli_args: {
'webdriver.chrome.driver': require('chromedriver').path
}
},
test_settings: {
default: {
selenium_port: 4444,
selenium_host: 'localhost',
silent: true,
globals: {
devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
}
},
chrome: {
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true
}
},
firefox: {
desiredCapabilities: {
browserName: 'firefox',
javascriptEnabled: true,
acceptSslCerts: true
}
}
}
}

View File

@ -0,0 +1,48 @@
// 1. start the dev server using production config
process.env.NODE_ENV = 'testing'
const webpack = require('webpack')
const DevServer = require('webpack-dev-server')
const webpackConfig = require('../../build/webpack.prod.conf')
const devConfigPromise = require('../../build/webpack.dev.conf')
let server
devConfigPromise.then(devConfig => {
const devServerOptions = devConfig.devServer
const compiler = webpack(webpackConfig)
server = new DevServer(compiler, devServerOptions)
const port = devServerOptions.port
const host = devServerOptions.host
return server.listen(port, host)
})
.then(() => {
// 2. run the nightwatch test suite against it
// to run in additional browsers:
// 1. add an entry in test/e2e/nightwatch.conf.js under "test_settings"
// 2. add it to the --env flag below
// or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
// For more information on Nightwatch's config file, see
// http://nightwatchjs.org/guide#settings-file
let opts = process.argv.slice(2)
if (opts.indexOf('--config') === -1) {
opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
}
if (opts.indexOf('--env') === -1) {
opts = opts.concat(['--env', 'chrome'])
}
const spawn = require('cross-spawn')
const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
runner.on('exit', function (code) {
server.close()
process.exit(code)
})
runner.on('error', function (err) {
server.close()
throw err
})
})

View File

@ -0,0 +1,19 @@
// For authoring Nightwatch tests, see
// http://nightwatchjs.org/guide#usage
module.exports = {
'default e2e tests': function (browser) {
// automatically uses dev Server port from /config.index.js
// default: http://localhost:8080
// see nightwatch.conf.js
const devServer = browser.globals.devServerURL
browser
.url(devServer)
.waitForElementVisible('#app', 5000)
.assert.elementPresent('.hello')
.assert.containsText('h1', 'Welcome to Your Vue.js App')
.assert.elementCount('img', 1)
.end()
}
}

View File

@ -0,0 +1,7 @@
{
"env": {
"jest": true
},
"globals": {
}
}

View File

@ -0,0 +1,30 @@
const path = require('path')
module.exports = {
rootDir: path.resolve(__dirname, '../../'),
moduleFileExtensions: [
'js',
'json',
'vue'
],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
transform: {
'^.+\\.js$': '<rootDir>/node_modules/babel-jest',
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
},
testPathIgnorePatterns: [
'<rootDir>/test/e2e'
],
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
setupFiles: ['<rootDir>/test/unit/setup'],
mapCoverage: true,
coverageDirectory: '<rootDir>/test/unit/coverage',
collectCoverageFrom: [
'src/**/*.{js,vue}',
'!src/main.js',
'!src/router/index.js',
'!**/node_modules/**'
]
}

View File

@ -0,0 +1,3 @@
import Vue from 'vue'
Vue.config.productionTip = false

View File

@ -0,0 +1,11 @@
import Vue from 'vue'
import HelloWorld from '@/components/HelloWorld'
describe('HelloWorld.vue', () => {
it('should render correct contents', () => {
const Constructor = Vue.extend(HelloWorld)
const vm = new Constructor().$mount()
expect(vm.$el.querySelector('.hello h1').textContent)
.toEqual('Welcome to Your Vue.js App')
})
})

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager;
package com.zhu.onemanager;
import org.junit.Test;
import org.junit.runner.RunWith;

View File

@ -0,0 +1,54 @@
package com.zhu.onemanager.controller;
import cn.hutool.http.HttpUtil;
import com.zhu.onemanager.controller.api.CallbackController;
import com.zhu.onemanager.logic.AuthUrl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class CallbackControllerTest {
@Resource
private AuthUrl authUrl;
@Resource
private CallbackController callbackController;
@Resource
private HttpServletRequest httpServletRequest;
@Resource
private HttpServletResponse httpServletResponse;
@Value("${onedrive.clientId}")
String clientId;
@Value("${onedrive.clientSecret}")
String clientSecret;
@Value("${onedrive.redirectUri}")
String redirectUri;
@Value("${onedrive.scope}")
String scope;
@Test
public void authCallback() {
String url = "https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=0d5e84db-18cf-4ab7-bc67-4af2dc9bce6b&redirect_uri=http://localhost:8081/api/outlook";
String res = HttpUtil.get(url);
//System.out.println("res = " + res);
}
@Test
public void outlookCallback() {
}
}

View File

@ -1,4 +1,4 @@
package com.dnslin.onemanager.test;
package com.zhu.onemanager.test;
import cn.hutool.core.util.RandomUtil;
import org.junit.Test;