Compare commits

...

27 Commits
1.2 ... 1.6

Author SHA1 Message Date
zhaojun1998
96ab8ff7dd 🔖 发布 1.6 版 2020-02-18 21:10:25 +08:00
zhaojun1998
8809aca170 📝 更新页面 2020-02-18 21:08:53 +08:00
zhaojun1998
97106383b6 🐛 修复使用本地存储时, 文件名中包含 + 引发的无法下载的 BUG. 2020-02-18 20:10:20 +08:00
zhaojun1998
208da95234 🐛 修复不同操作系统, 可能出现的编码问题, 导致导入的数据库文件乱码. 2020-02-18 20:09:32 +08:00
zhaojun1998
d4c843f5f5 🐛 修复 OneDrive 文件夹中包含 + 号, 且文件夹中的内容大于 200 个时, 请求出错的 BUG. 2020-02-18 20:02:37 +08:00
zhaojun1998
d273fc9f12 📝 更新文档 2020-02-15 18:39:56 +08:00
zhaojun1998
0b4a38218c 🔖 发布 1.5 版 2020-02-15 18:25:41 +08:00
zhaojun1998
2f57c5b5cc 新增功能: 自定义表格大小, 显示操作按钮, 显示文档, 公告信息 2020-02-15 18:22:37 +08:00
zhaojun1998
610f68295f 📝 更新页面 2020-02-15 18:22:01 +08:00
zhaojun1998
39ced8eb84 📝 更新页面 2020-02-15 18:05:43 +08:00
zhaojun1998
368b7a1df2 优化排序方式为自然排序 2020-02-14 20:22:22 +08:00
zhaojun1998
8e2107cd46 📝 更新开发计划 2020-02-11 18:27:34 +08:00
zhaojun1998
fa32a33371 📝 更新页面 2020-02-09 21:49:27 +08:00
zhaojun1998
59116a9414 🔖 发布 1.4.1 版 2020-02-09 21:47:27 +08:00
zhaojun1998
b2c732a389 🐛 修复 URL 中包含特殊字符, 返回 400 错误的 BUG. 2020-02-09 21:35:25 +08:00
zhaojun1998
0e1ffef92b 🔖 发布 1.4 版 2020-02-09 18:06:50 +08:00
zhaojun1998
a5b19d3577 新增获取直链下载功能. 2020-02-09 18:06:42 +08:00
zhaojun1998
185c84dd79 新增获取直链下载功能. 2020-02-09 18:05:56 +08:00
zhaojun1998
d554dd298c 优化 OneDrive 相关代码结构. 2020-02-09 18:05:01 +08:00
zhaojun1998
aa6ecf0aaa 优化 OneDrive 相关代码结构. 2020-02-09 18:04:33 +08:00
zhaojun1998
83692718e3 📝 更新页面 2020-02-09 18:01:57 +08:00
zhaojun1998
030bd95941 🔖 发布 1.3 版 2020-02-08 17:47:37 +08:00
zhaojun1998
8722d11ac3 📝 更新页面 2020-02-08 17:46:33 +08:00
zhaojun1998
0131ff02c0 🐛 修复头部文件和密码文件, 在开启缓存的状态下, 仅第一次生效的 BUG. 2020-02-08 17:43:02 +08:00
zhaojun1998
2d115bf1c6 更改本地存储, 文件下载时, 文件不存在的响应状态码为 404. 2020-02-08 17:14:01 +08:00
zhaojun1998
946113216d 🔖 发布 1.2.1 版 2020-02-03 20:57:07 +08:00
zhaojun1998
77b05c6dac 🐛 修复 OneDrive 的 Token 某些情况下, 可能超出 2000 字符的 BUG 2020-02-03 20:52:49 +08:00
40 changed files with 481 additions and 272 deletions

2
API.md
View File

@@ -145,7 +145,7 @@
"msg": "操作成功",
"code": 0,
"data": {
"header": null, # 头部文件名称
"readme": null, # 文档文件名称
"viewConfig": {
"siteName": "站点名称", # 站点名称
"infoEnable": false, # 是否开启右侧信息框

View File

@@ -10,13 +10,14 @@
前端基于 [h5ai](https://larsjung.de/h5ai/) 的原有功能使用 Vue 重新开发了一遍. 后端采用 SpringBoot, 数据库采用内嵌数据库.
预览地址: [https://zfile.jun6.net](https://zfile.jun6.net)
文档地址: [http://docs.zhaojun.im/zfile](http://docs.zhaojun.im/zfile)
## 系统特色
* 内存缓存 (免安装)
* 内存数据库 (免安装)
* 个性化配置
* 自定义目录的 header 说明文件
* 自定义目录的 readme 说明文件
* 自定义 JS, CSS
* 文件夹密码
* 支持在线浏览文本文件, 视频, 图片, 音乐. (支持 FLV 和 HLS)
@@ -43,9 +44,9 @@ apt install -y openjdk-8-jre-headless unzip
下载项目:
```bash
wget -P ~ https://c.jun6.net/ZFILE/zfile-1.2.war
wget -P ~ https://c.jun6.net/ZFILE/zfile-release.war
cd ~
mkdir zfile && unzip zfile-1.2.war -d zfile && rm -rf zfile-1.2.war
mkdir zfile && unzip zfile-release.war -d zfile && rm -rf zfile-release.war
chmod +x ~/zfile/bin/*.sh
```
@@ -119,19 +120,27 @@ https://login.chinacloudapi.cn/common/oauth2/v2.0/authorize?client_id=4a72d927-1
默认 H2 数据库文件地址: `~/.zfile/db/`, `~` 表示用户目录, windows 为 `C:/Users/用户名/`, linux 为 `/home/用户名/`, root 用户为 `/root/`
### 头尾文件和加密文件
### 文档文件和加密文件
- 目录头部显示文件名为 `header.md`
- 目录文档显示文件名为 `readme.md`
- 目录需要密码访问, 添加文件 `password.txt` (无法拦截此文件被下载, 但可以改名文件)
## TODO
## 开发计划
- [x] API 支持 [点击查看文档](https://github.com/zhaojun1998/zfile/blob/master/API.md)
- [x] 更方便的部署方式
- [ ] 文本预览更换更好用的编辑器
- [ ] 后台支持上传、编辑、删除等操作
- [ ] WebDav 支持
- [ ] Docker 支持
- [ ] 新功能 - 后台支持上传、编辑、删除等操作
- [ ] 新功能 - WebDav 支持
- [ ] 新功能 - Docker 支持
- [ ] 新功能 - 离线下载 (aria2)
- [ ] 体验优化 - 文本预览更换 vscode 同款编辑器 monaco editor
- [ ] 体验优化 - 忽略文件列表 (正则表达式)
- [ ] 体验优化 - 自定义支持预览的文件后缀 (正则表达式)
- [ ] 布局优化 - 底部增加固定栏, 用于填写备案信息, 友情链接等信息.
- [ ] 布局优化 - 自定义操作按钮 (现为右键实现)
- [ ] 后台优化 - 设置按照其功能进行分离
- [ ] 架构调整 - 支持多存储策略
- [ ] 体验优化 - 一键安装脚本
## 支持作者

View File

@@ -12,7 +12,7 @@
<groupId>im.zhaojun</groupId>
<artifactId>zfile</artifactId>
<version>1.2</version>
<version>1.6</version>
<name>zfile</name>
<packaging>war</packaging>
<description>一个在线的文件浏览系统</description>
@@ -148,7 +148,7 @@
<configuration>
<jvms>
<jvm>-server</jvm>
<jvm>-Xmx512m</jvm>
<jvm>-Xmx300m -Xmx100m</jvm>
<jvm>-Djava.security.egd=file:/dev/./urandom</jvm>
</jvms>
</configuration>

View File

@@ -1,15 +1,10 @@
package im.zhaojun.common.config;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.service.SystemConfigService;
import im.zhaojun.onedrive.china.service.OneDriveChinaService;
import im.zhaojun.onedrive.china.service.OneDriveServiceChinaImpl;
import im.zhaojun.onedrive.common.model.OneDriveToken;
import im.zhaojun.onedrive.international.service.OneDriveService;
import im.zhaojun.onedrive.china.service.OneDriveChinaServiceImpl;
import im.zhaojun.onedrive.international.service.OneDriveServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
@@ -18,7 +13,6 @@ import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;
/**
@@ -33,10 +27,10 @@ public class GlobalScheduleTask {
private StorageConfigService storageConfigService;
@Resource
private OneDriveService oneDriveService;
private OneDriveServiceImpl oneDriveServiceImpl;
@Resource
private OneDriveChinaService oneDriveChinaService;
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
@Resource
private SystemConfigService systemConfigService;
@@ -50,7 +44,7 @@ public class GlobalScheduleTask {
AbstractFileService currentFileService = systemConfigService.getCurrentFileService();
if (!(currentFileService instanceof OneDriveServiceImpl
|| currentFileService instanceof OneDriveServiceChinaImpl)) {
|| currentFileService instanceof OneDriveChinaServiceImpl)) {
log.debug("当前启用存储类型, 不是 OneDrive, 跳过自动刷新 AccessToken");
return;
}
@@ -77,27 +71,11 @@ public class GlobalScheduleTask {
* 调用刷新 OneDrive Token
*/
public void refreshOneDriveToken(StorageTypeEnum storageType) {
OneDriveToken refreshToken;
if (Objects.equals(storageType, StorageTypeEnum.ONE_DRIVE_CHINA)) {
refreshToken = oneDriveChinaService.getRefreshToken(storageType);
oneDriveChinaServiceImpl.refreshOneDriveToken();
} else {
refreshToken = oneDriveService.getRefreshToken(storageType);
oneDriveServiceImpl.refreshOneDriveToken();
}
if (refreshToken.getAccessToken() == null || refreshToken.getRefreshToken() == null) {
return;
}
StorageConfig accessTokenConfig =
storageConfigService.selectByTypeAndKey(storageType, StorageConfigConstant.ACCESS_TOKEN_KEY);
StorageConfig refreshTokenConfig =
storageConfigService.selectByTypeAndKey(storageType, StorageConfigConstant.REFRESH_TOKEN_KEY);
accessTokenConfig.setValue(refreshToken.getAccessToken());
refreshTokenConfig.setValue(refreshToken.getRefreshToken());
storageConfigService.updateStorageConfig(Arrays.asList(accessTokenConfig, refreshTokenConfig));
log.info("刷新 {} key 时间: {}", storageType.getDescription(), LocalDateTime.now());
}
}

View File

@@ -1,6 +1,9 @@
package im.zhaojun.common.config;
import im.zhaojun.common.model.enums.StorageTypeEnumDeSerializerConvert;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -15,4 +18,14 @@ public class WebMvcConfig implements WebMvcConfigurer {
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StorageTypeEnumDeSerializerConvert());
}
@Bean
public ServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory webServerFactory = new TomcatServletWebServerFactory();
webServerFactory.addConnectorCustomizers(connector -> {
connector.setAttribute("relaxedPathChars", "<>[\\]^`{|}");
connector.setAttribute("relaxedQueryChars", "<>[\\]^`{|}");
});
return webServerFactory;
}
}

View File

@@ -23,6 +23,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
@@ -72,7 +74,7 @@ public class FileController {
/**
* 获取系统配置信息和当前页的标题, 文件头, 文件尾信息
* 获取系统配置信息和当前页的标题, 页面文档信息
* @param path 路径
*/
@CheckStorageStrategyInit
@@ -105,7 +107,7 @@ public class FileController {
/**
* 过滤文件列表, 不显示密码, 头部和尾部文件.
* 过滤文件列表, 不显示密码, 文档文件.
*/
private void filterFileList(List<FileItemDTO> fileItemList) {
if (fileItemList == null) {
@@ -113,16 +115,19 @@ public class FileController {
}
fileItemList.removeIf(fileItem -> ZFileConstant.PASSWORD_FILE_NAME.equals(fileItem.getName())
|| ZFileConstant.HEADER_FILE_NAME.equals(fileItem.getName()));
|| ZFileConstant.README_FILE_NAME.equals(fileItem.getName()));
}
private List<FileItemDTO> getSortedPagingData(List<FileItemDTO> fileItemList, Integer page) {
// 排序, 先按照文件类型比较, 文件夹在前, 文件在后, 然后根据 sortBy 字段排序, 默认为升序;
fileItemList.sort(new FileComparator());
filterFileList(fileItemList);
ArrayList<FileItemDTO> copy = new ArrayList<>(Arrays.asList(new FileItemDTO[fileItemList.size()]));
Collections.copy(copy, fileItemList);
int total = fileItemList.size();
// 排序, 先按照文件类型比较, 文件夹在前, 文件在后, 然后根据 sortBy 字段排序, 默认为升序;
copy.sort(new FileComparator());
filterFileList(copy);
int total = copy.size();
int totalPage = (total + PAGE_SIZE - 1) / PAGE_SIZE;
if (page > totalPage) {
@@ -132,7 +137,7 @@ public class FileController {
int start = (page - 1) * PAGE_SIZE;
int end = page * PAGE_SIZE;
end = Math.min(end, total);
return new ArrayList<>(fileItemList.subList(start, end));
return new ArrayList<>(copy.subList(start, end));
}

View File

@@ -0,0 +1,63 @@
package im.zhaojun.common.controller;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.SystemConfigService;
import org.springframework.stereotype.Controller;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.HandlerMapping;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.MalformedURLException;
import java.util.Objects;
/**
* @author Zhao Jun
* 2020/2/9 11:17
*/
@Controller
public class PageController {
@Resource
private SystemConfigService systemConfigService;
@GetMapping("/directlink/**")
public String directlink(final HttpServletRequest request) throws MalformedURLException {
String path = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
AntPathMatcher apm = new AntPathMatcher();
String filePath = apm.extractPathWithinPattern(bestMatchPattern, path);
if (filePath.length() > 0 && filePath.charAt(0) != '/') {
filePath = "/" + filePath;
}
AbstractFileService fileService = systemConfigService.getCurrentFileService();
FileItemDTO fileItem = fileService.getFileItem(filePath);
String url = fileItem.getUrl();
int queryIndex = url.indexOf('?');
if (queryIndex != -1) {
String origin = url.substring(0, queryIndex);
String queryString = url.substring(queryIndex + 1);
url = URLUtil.encode(origin) + "?" + URLUtil.encode(queryString);
} else {
url = URLUtil.encode(url);
}
if (Objects.equals(fileItem.getType(), FileTypeEnum.FOLDER)) {
return "redirect:" + fileItem.getUrl();
} else {
return "redirect:" + url;
}
}
}

View File

@@ -27,7 +27,7 @@ public class StorageConfig {
private String title;
@Column(length = 2048)
@Column(length = 4000)
private String value;
public Integer getId() {

View File

@@ -15,9 +15,9 @@ public class ZFileConstant {
public static final String AUDIO_TMP_PATH = "/.zfile/tmp/audio/";
/**
* 页面头部文件
* 页面文档文件
*/
public static String HEADER_FILE_NAME = "header.md";
public static String README_FILE_NAME = "readme.md";
/**
* 密码文件
@@ -25,8 +25,8 @@ public class ZFileConstant {
public static String PASSWORD_FILE_NAME = "password.txt";
@Autowired(required = false)
public void setHeaderFileName(@Value("${zfile.constant.header}") String headerFileName) {
ZFileConstant.HEADER_FILE_NAME = headerFileName;
public void setHeaderFileName(@Value("${zfile.constant.readme}") String headerFileName) {
ZFileConstant.README_FILE_NAME = headerFileName;
}
@Autowired(required = false)

View File

@@ -15,7 +15,7 @@ public class SiteConfigDTO implements Serializable {
private static final long serialVersionUID = 8811196207046121740L;
private String header;
private String readme;
@JsonProperty("viewConfig")
private SystemConfigDTO systemConfigDTO;

View File

@@ -44,4 +44,15 @@ public class SystemConfigDTO {
private String customCss;
private String tableSize;
private Boolean showOperator;
private Boolean showDocument;
private String announcement;
private Boolean showAnnouncement;
private String layout;
}

View File

@@ -1,7 +1,6 @@
package im.zhaojun.common.service;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ListObjectsRequest;
@@ -112,11 +111,21 @@ public abstract class AbstractS3FileService extends AbstractFileService {
@Override
public FileItemDTO getFileItem(String path) {
List<FileItemDTO> list = fileList(path);
if (list == null || list.size() == 0) {
List<FileItemDTO> list;
try {
int end = path.lastIndexOf("/");
list = fileList(path.substring(0, end + 1));
} catch (Exception e) {
throw new NotExistFileException();
}
return list.get(0);
for (FileItemDTO fileItemDTO : list) {
String fullPath = StringUtils.concatUrl(fileItemDTO.getPath(), fileItemDTO.getName());
if (Objects.equals(fullPath, path)) {
return fileItemDTO;
}
}
throw new NotExistFileException();
}
}

View File

@@ -20,7 +20,7 @@ public class SystemService {
private SystemConfigService systemConfigService;
/**
* 构建指定路径下标题, 页头, 页尾
* 构建指定路径下标题, 页面文档信息
* @param path 路径
*/
public synchronized SiteConfigDTO getConfig(String path) throws Exception {
@@ -30,8 +30,8 @@ public class SystemService {
List<FileItemDTO> fileItemList = new ArrayList<>(fileService.fileList(path));
for (FileItemDTO fileItemDTO : fileItemList) {
if (ZFileConstant.HEADER_FILE_NAME.equalsIgnoreCase(fileItemDTO.getName())) {
siteConfigDTO.setHeader(HttpUtil.getTextContent(fileItemDTO.getUrl()));
if (ZFileConstant.README_FILE_NAME.equalsIgnoreCase(fileItemDTO.getName())) {
siteConfigDTO.setReadme(HttpUtil.getTextContent(fileItemDTO.getUrl()));
}
}
return siteConfigDTO;

View File

@@ -37,16 +37,15 @@ public class FileComparator implements Comparator<FileItemDTO> {
if (order == null) {
order = "asc";
}
FileTypeEnum o1Type = o1.getType();
FileTypeEnum o2Type = o2.getType();
NaturalOrderComparator naturalOrderComparator = new NaturalOrderComparator();
if (o1Type.equals(o2Type)) {
int result;
switch (sortBy) {
case "time": result = o1.getTime().compareTo(o2.getTime()); break;
case "size": result = o1.getSize().compareTo(o2.getSize()); break;
default: result = o1.getName().compareToIgnoreCase(o2.getName()); break;
default: result = naturalOrderComparator.compare(o1.getName(), o2.getName()); break;
}
return "asc".equals(order) ? result : -result;
}
@@ -57,4 +56,4 @@ public class FileComparator implements Comparator<FileItemDTO> {
return 1;
}
}
}
}

View File

@@ -0,0 +1,142 @@
package im.zhaojun.common.util;
/*
NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>
Based on the C version by Martin Pool, of which this is more or less a straight conversion.
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
import java.util.Comparator;
public class NaturalOrderComparator implements Comparator<String> {
private int compareRight(String a, String b) {
int bias = 0, ia = 0, ib = 0;
// The longest run of digits wins. That aside, the greatest
// value wins, but we can't know that it will until we've scanned
// both numbers to know that they have the same magnitude, so we
// remember it in BIAS.
for (; ; ia++, ib++) {
char ca = charAt(a, ia);
char cb = charAt(b, ib);
if (!isDigit(ca) && !isDigit(cb)) {
return bias;
}
if (!isDigit(ca)) {
return -1;
}
if (!isDigit(cb)) {
return +1;
}
if (ca == 0 && cb == 0) {
return bias;
}
if (bias == 0) {
if (ca < cb) {
bias = -1;
} else if (ca > cb) {
bias = +1;
}
}
}
}
public int compare(String a, String b) {
int ia = 0, ib = 0;
int nza = 0, nzb = 0;
char ca, cb;
while (true) {
// Only count the number of zeroes leading the last number compared
nza = nzb = 0;
ca = charAt(a, ia);
cb = charAt(b, ib);
// skip over leading spaces or zeros
while (Character.isSpaceChar(ca) || ca == '0') {
if (ca == '0') {
nza++;
} else {
// Only count consecutive zeroes
nza = 0;
}
ca = charAt(a, ++ia);
}
while (Character.isSpaceChar(cb) || cb == '0') {
if (cb == '0') {
nzb++;
} else {
// Only count consecutive zeroes
nzb = 0;
}
cb = charAt(b, ++ib);
}
// Process run of digits
if (Character.isDigit(ca) && Character.isDigit(cb)) {
int bias = compareRight(a.substring(ia), b.substring(ib));
if (bias != 0) {
return bias;
}
}
if (ca == 0 && cb == 0) {
// The strings compare the same. Perhaps the caller
// will want to call strcmp to break the tie.
return compareEqual(a, b, nza, nzb);
}
if (ca < cb) {
return -1;
}
if (ca > cb) {
return +1;
}
++ia;
++ib;
}
}
private static boolean isDigit(char c) {
return Character.isDigit(c) || c == '.' || c == ',';
}
private static char charAt(String s, int i) {
return i >= s.length() ? 0 : s.charAt(i);
}
private static int compareEqual(String a, String b, int nza, int nzb) {
if (nza - nzb != 0)
return nza - nzb;
if (a.length() == b.length())
return a.compareTo(b);
return a.length() - b.length();
}
}

View File

@@ -1,11 +1,11 @@
package im.zhaojun.local.controller;
import cn.hutool.core.util.URLUtil;
import im.zhaojun.common.exception.NotExistFileException;
import im.zhaojun.common.util.StringUtils;
import im.zhaojun.local.service.LocalServiceImpl;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
@@ -30,20 +30,20 @@ public class LocalController {
@GetMapping("/file/**")
@ResponseBody
public ResponseEntity<FileSystemResource> downAttachment(final HttpServletRequest request) {
public ResponseEntity<Object> downAttachment(final HttpServletRequest request) {
String path = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
AntPathMatcher apm = new AntPathMatcher();
String filePath = apm.extractPathWithinPattern(bestMatchPattern, path);
return export(new File(StringUtils.concatPath(localServiceImpl.getFilePath(), URLUtil.decode(filePath))));
return export(new File(StringUtils.concatPath(localServiceImpl.getFilePath(), filePath)));
}
private ResponseEntity<FileSystemResource> export(File file) {
private ResponseEntity<Object> export(File file) {
if (!file.exists()) {
throw new NotExistFileException();
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("404 FILE NOT FOUND");
}

View File

@@ -90,7 +90,7 @@ public class LocalServiceImpl extends AbstractFileService implements FileService
@Override
public String getDownloadUrl(String path) {
SystemConfig usernameConfig = systemConfigRepository.findByKey(SystemConfigConstant.DOMAIN);
return URLUtil.encode(StringUtils.removeDuplicateSeparator(usernameConfig.getValue() + "/file/" + path));
return StringUtils.removeDuplicateSeparator(usernameConfig.getValue() + "/file/" + path);
}
public String getFilePath() {

View File

@@ -1,54 +0,0 @@
package im.zhaojun.onedrive.china.service;
import im.zhaojun.onedrive.common.service.AbstractOneDriveService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @author zhaojun
*/
@Service
public class OneDriveChinaService extends AbstractOneDriveService {
@Value("${zfile.onedirve-china.clientId}")
private String clientId;
@Value("${zfile.onedirve-china.redirectUri}")
private String redirectUri;
@Value("${zfile.onedirve-china.clientSecret}")
private String clientSecret;
@Value("${zfile.onedirve-china.scope}")
private String scope;
@Override
public String getGraphEndPoint() {
return "microsoftgraph.chinacloudapi.cn";
}
@Override
public String getAuthenticateEndPoint() {
return "login.partner.microsoftonline.cn";
}
@Override
public String getClientId() {
return clientId;
}
@Override
public String getRedirectUri() {
return redirectUri;
}
@Override
public String getClientSecret() {
return clientSecret;
}
@Override
public String getScope() {
return scope;
}
}

View File

@@ -1,20 +1,18 @@
package im.zhaojun.onedrive.china.service;
import im.zhaojun.common.config.GlobalScheduleTask;
import im.zhaojun.common.exception.NotExistFileException;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.onedrive.common.service.AbstractOneDriveService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
@@ -22,7 +20,7 @@ import java.util.Map;
*/
@Service
@Slf4j
public class OneDriveServiceChinaImpl extends AbstractFileService implements FileService {
public class OneDriveChinaServiceImpl extends AbstractOneDriveService implements FileService {
@Resource
private GlobalScheduleTask globalScheduleTask;
@@ -30,8 +28,17 @@ public class OneDriveServiceChinaImpl extends AbstractFileService implements Fil
@Resource
private StorageConfigService storageConfigService;
@Resource
private OneDriveChinaService oneDriveChinaService;
@Value("${zfile.onedirve-china.clientId}")
private String clientId;
@Value("${zfile.onedirve-china.redirectUri}")
private String redirectUri;
@Value("${zfile.onedirve-china.clientSecret}")
private String clientSecret;
@Value("${zfile.onedirve-china.scope}")
private String scope;
@Override
public void init() {
@@ -46,7 +53,7 @@ public class OneDriveServiceChinaImpl extends AbstractFileService implements Fil
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
isInitialized = false;
} else {
globalScheduleTask.refreshOneDriveToken(getStorageTypeEnum());
refreshOneDriveToken();
isInitialized = testConnection();
}
} catch (Exception e) {
@@ -54,11 +61,6 @@ public class OneDriveServiceChinaImpl extends AbstractFileService implements Fil
}
}
@Override
public List<FileItemDTO> fileList(String path) {
return oneDriveChinaService.list(basePath, path);
}
@Override
public String getDownloadUrl(String path) {
return null;
@@ -70,14 +72,32 @@ public class OneDriveServiceChinaImpl extends AbstractFileService implements Fil
}
@Override
public FileItemDTO getFileItem(String path) {
FileItemDTO fileItemDTO ;
public String getGraphEndPoint() {
return "microsoftgraph.chinacloudapi.cn";
}
try {
fileItemDTO = oneDriveChinaService.getItem(path);
} catch (Exception e) {
throw new NotExistFileException();
}
return fileItemDTO;
@Override
public String getAuthenticateEndPoint() {
return "login.partner.microsoftonline.cn";
}
@Override
public String getClientId() {
return clientId;
}
@Override
public String getRedirectUri() {
return redirectUri;
}
@Override
public String getClientSecret() {
return clientSecret;
}
@Override
public String getScope() {
return scope;
}
}

View File

@@ -4,8 +4,8 @@ import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.onedrive.china.service.OneDriveChinaService;
import im.zhaojun.onedrive.international.service.OneDriveService;
import im.zhaojun.onedrive.china.service.OneDriveChinaServiceImpl;
import im.zhaojun.onedrive.international.service.OneDriveServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
@@ -26,11 +26,11 @@ public class OneDriveConfig {
@Resource
@Lazy
private OneDriveService oneDriveService;
private OneDriveServiceImpl oneDriveServiceImpl;
@Resource
@Lazy
private OneDriveChinaService oneDriveChinaService;
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
@Bean
public RestTemplate oneDriveRestTemplate() {
@@ -39,9 +39,9 @@ public class OneDriveConfig {
ClientHttpRequestInterceptor interceptor = (httpRequest, bytes, clientHttpRequestExecution) -> {
String host = httpRequest.getURI().getHost();
StorageTypeEnum type;
if (oneDriveChinaService.getGraphEndPoint().contains(host)) {
if (oneDriveChinaServiceImpl.getGraphEndPoint().contains(host)) {
type = StorageTypeEnum.ONE_DRIVE_CHINA;
} else if (oneDriveService.getGraphEndPoint().contains(host)) {
} else if (oneDriveServiceImpl.getGraphEndPoint().contains(host)) {
type = StorageTypeEnum.ONE_DRIVE;
} else {
return clientHttpRequestExecution.execute(httpRequest, bytes);

View File

@@ -1,8 +1,8 @@
package im.zhaojun.onedrive.common.controller;
import im.zhaojun.onedrive.china.service.OneDriveChinaService;
import im.zhaojun.onedrive.china.service.OneDriveChinaServiceImpl;
import im.zhaojun.onedrive.common.model.OneDriveToken;
import im.zhaojun.onedrive.international.service.OneDriveService;
import im.zhaojun.onedrive.international.service.OneDriveServiceImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@@ -18,14 +18,14 @@ import javax.annotation.Resource;
public class OneDriveController {
@Resource
private OneDriveService oneDriveService;
private OneDriveServiceImpl oneDriveServiceImpl;
@Resource
private OneDriveChinaService oneDriveChinaService;
private OneDriveChinaServiceImpl oneDriveChinaServiceImpl;
@GetMapping("/callback")
public String onedriveCallback(String code, Model model) {
OneDriveToken oneDriveToken = oneDriveService.getToken(code);
OneDriveToken oneDriveToken = oneDriveServiceImpl.getToken(code);
model.addAttribute("accessToken", oneDriveToken.getAccessToken());
model.addAttribute("refreshToken", oneDriveToken.getRefreshToken());
return "callback";
@@ -34,7 +34,7 @@ public class OneDriveController {
@GetMapping("/china-callback")
public String onedriveChinaCallback(String code, Model model) {
OneDriveToken oneDriveToken = oneDriveChinaService.getToken(code);
OneDriveToken oneDriveToken = oneDriveChinaServiceImpl.getToken(code);
model.addAttribute("accessToken", oneDriveToken.getAccessToken());
model.addAttribute("refreshToken", oneDriveToken.getRefreshToken());
return "callback";

View File

@@ -11,8 +11,9 @@ import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.FileTypeEnum;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.repository.StorageConfigRepository;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.common.util.StringUtils;
import im.zhaojun.onedrive.common.model.OneDriveToken;
import org.springframework.http.ResponseEntity;
@@ -20,14 +21,16 @@ import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Zhao Jun
* 2020/1/29 11:54
*/
public abstract class AbstractOneDriveService {
public abstract class AbstractOneDriveService extends AbstractFileService {
protected static final String DRIVER_INFO_URL = "https://{graphEndPoint}/v1.0/me/drives";
@@ -45,9 +48,12 @@ public abstract class AbstractOneDriveService {
@Resource
private StorageConfigRepository storageConfigRepository;
public OneDriveToken getRefreshToken(StorageTypeEnum storageType) {
@Resource
private StorageConfigService storageConfigService;
public OneDriveToken getRefreshToken() {
StorageConfig refreshStorageConfig =
storageConfigRepository.findByTypeAndKey(storageType, StorageConfigConstant.REFRESH_TOKEN_KEY);
storageConfigRepository.findByTypeAndKey(this.getStorageTypeEnum(), StorageConfigConstant.REFRESH_TOKEN_KEY);
String param = "client_id=" + getClientId() +
"&redirect_uri=" + getRedirectUri() +
@@ -79,13 +85,12 @@ public abstract class AbstractOneDriveService {
return JSONObject.parseObject(response.body(), OneDriveToken.class);
}
public String getUserInfo() {
return oneDriveRestTemplate.getForObject(DRIVER_INFO_URL, String.class);
}
public List<FileItemDTO> list(String basePath, String path) {
@Override
public List<FileItemDTO> fileList(String path) {
path = StringUtils.removeFirstSeparator(path);
String fullPath = StringUtils.getFullPath(basePath, path);
@@ -97,6 +102,7 @@ public abstract class AbstractOneDriveService {
String requestUrl;
if (nextLink != null) {
nextLink = nextLink.replace("+", "%2B");
requestUrl = URLUtil.decode(nextLink);
}else if ("/".equalsIgnoreCase(fullPath) || "".equalsIgnoreCase(fullPath)) {
requestUrl = DRIVER_ROOT_URL;
@@ -137,11 +143,14 @@ public abstract class AbstractOneDriveService {
return result;
}
@Override
public FileItemDTO getFileItem(String path) {
String fullPath = StringUtils.getFullPath(basePath, path);
public FileItemDTO getItem(String path) {
String requestUrl;
ResponseEntity<String> responseEntity = oneDriveRestTemplate.getForEntity(DRIVER_ITEM_URL, String.class, path);
ResponseEntity<String> responseEntity = oneDriveRestTemplate.getForEntity(DRIVER_ITEM_URL, String.class, getGraphEndPoint(), fullPath);
String body = responseEntity.getBody();
JSONObject fileItem = JSON.parseObject(body);
@@ -174,4 +183,21 @@ public abstract class AbstractOneDriveService {
public abstract String getClientSecret();
public abstract String getScope();
public void refreshOneDriveToken() {
OneDriveToken refreshToken = getRefreshToken();
if (refreshToken.getAccessToken() == null || refreshToken.getRefreshToken() == null) {
return;
}
StorageConfig accessTokenConfig =
storageConfigService.selectByTypeAndKey(this.getStorageTypeEnum(), StorageConfigConstant.ACCESS_TOKEN_KEY);
StorageConfig refreshTokenConfig =
storageConfigService.selectByTypeAndKey(this.getStorageTypeEnum(), StorageConfigConstant.REFRESH_TOKEN_KEY);
accessTokenConfig.setValue(refreshToken.getAccessToken());
refreshTokenConfig.setValue(refreshToken.getRefreshToken());
storageConfigService.updateStorageConfig(Arrays.asList(accessTokenConfig, refreshTokenConfig));
}
}

View File

@@ -1,54 +0,0 @@
package im.zhaojun.onedrive.international.service;
import im.zhaojun.onedrive.common.service.AbstractOneDriveService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @author zhaojun
*/
@Service
public class OneDriveService extends AbstractOneDriveService {
@Value("${zfile.onedirve.clientId}")
protected String clientId;
@Value("${zfile.onedirve.redirectUri}")
protected String redirectUri;
@Value("${zfile.onedirve.clientSecret}")
protected String clientSecret;
@Value("${zfile.onedirve.scope}")
protected String scope;
@Override
public String getGraphEndPoint() {
return "graph.microsoft.com";
}
@Override
public String getAuthenticateEndPoint() {
return "login.microsoftonline.com";
}
@Override
public String getClientId() {
return clientId;
}
@Override
public String getRedirectUri() {
return redirectUri;
}
@Override
public String getClientSecret() {
return clientSecret;
}
@Override
public String getScope() {
return scope;
}
}

View File

@@ -1,20 +1,18 @@
package im.zhaojun.onedrive.international.service;
import im.zhaojun.common.config.GlobalScheduleTask;
import im.zhaojun.common.exception.NotExistFileException;
import im.zhaojun.common.model.StorageConfig;
import im.zhaojun.common.model.constant.StorageConfigConstant;
import im.zhaojun.common.model.dto.FileItemDTO;
import im.zhaojun.common.model.enums.StorageTypeEnum;
import im.zhaojun.common.service.AbstractFileService;
import im.zhaojun.common.service.FileService;
import im.zhaojun.common.service.StorageConfigService;
import im.zhaojun.onedrive.common.service.AbstractOneDriveService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
@@ -22,7 +20,7 @@ import java.util.Map;
*/
@Service
@Slf4j
public class OneDriveServiceImpl extends AbstractFileService implements FileService {
public class OneDriveServiceImpl extends AbstractOneDriveService implements FileService {
@Resource
private GlobalScheduleTask globalScheduleTask;
@@ -30,8 +28,17 @@ public class OneDriveServiceImpl extends AbstractFileService implements FileServ
@Resource
private StorageConfigService storageConfigService;
@Resource
private OneDriveService oneDriveService;
@Value("${zfile.onedirve.clientId}")
protected String clientId;
@Value("${zfile.onedirve.redirectUri}")
protected String redirectUri;
@Value("${zfile.onedirve.clientSecret}")
protected String clientSecret;
@Value("${zfile.onedirve.scope}")
protected String scope;
@Override
public void init() {
@@ -46,7 +53,7 @@ public class OneDriveServiceImpl extends AbstractFileService implements FileServ
log.debug("初始化存储策略 [{}] 失败: 参数不完整", getStorageTypeEnum().getDescription());
isInitialized = false;
} else {
globalScheduleTask.refreshOneDriveToken(getStorageTypeEnum());
refreshOneDriveToken();
isInitialized = testConnection();
}
} catch (Exception e) {
@@ -54,11 +61,6 @@ public class OneDriveServiceImpl extends AbstractFileService implements FileServ
}
}
@Override
public List<FileItemDTO> fileList(String path) {
return oneDriveService.list(basePath, path);
}
@Override
public String getDownloadUrl(String path) {
return null;
@@ -70,14 +72,32 @@ public class OneDriveServiceImpl extends AbstractFileService implements FileServ
}
@Override
public FileItemDTO getFileItem(String path) {
FileItemDTO fileItemDTO ;
try {
fileItemDTO = oneDriveService.getItem(path);
} catch (Exception e) {
throw new NotExistFileException();
}
return fileItemDTO;
public String getGraphEndPoint() {
return "graph.microsoft.com";
}
}
@Override
public String getAuthenticateEndPoint() {
return "login.microsoftonline.com";
}
@Override
public String getClientId() {
return clientId;
}
@Override
public String getRedirectUri() {
return redirectUri;
}
@Override
public String getClientSecret() {
return clientSecret;
}
@Override
public String getScope() {
return scope;
}
}

View File

@@ -6,10 +6,10 @@
"description": "目录缓存过期时间 和 下载地址过期时间. 单位为秒."
},
{
"name": "zfile.constant.header",
"name": "zfile.constant.readme",
"type": "java.lang.String",
"defaultValue": "header.md",
"description": "头部文件 文件名."
"defaultValue": "readme.md",
"description": "文档文件 文件名."
},
{
"name": "zfile.constant.password",

View File

@@ -17,6 +17,8 @@ spring:
datasource:
# 初始化数据导入
data: classpath*:db/data.sql
sql-script-encoding: utf-8
initialization-mode: always
continue-on-error: true
@@ -27,7 +29,7 @@ spring:
password: 123456
# MySQL 配置
# driver-class-name: com.mysql.jdbc.Driver
# driver-class-name: com.mysql.jdbc.Driver
# url: jdbc:mysql://127.0.0.1:3306/zfile?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
# username: root
# password: 123456
@@ -46,11 +48,15 @@ spring:
gzipped: true
profiles:
active: prod
boot:
admin:
context-path: /act
zfile:
cache:
timeout: 300
constant:
header: header.md
readme: readme.md
password: password.txt
onedirve:
clientId: 09939809-c617-43c8-a220-a93c1513c5d4
@@ -69,4 +75,7 @@ jetcache:
local:
default:
type: caffeine
keyConvertor: fastjson
keyConvertor: fastjson

View File

@@ -10,6 +10,12 @@ INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (9, 'enableCache', '是
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (10, 'searchContainEncryptedFile', '搜索包含加密文件');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (11, 'customCss', '自定义 CSS');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (12, 'customJs', '自定义 JS (可用于统计代码)');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (13, 'tableSize', '表格大小');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (14, 'showOperator', '是否显示操作按钮');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (15, 'showDocument', '是否显示文档');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (16, 'announcement', '网站公告');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (17, 'showAnnouncement', '是否显示网站公告');
INSERT INTO SYSTEM_CONFIG (`ID`, `k`, `REMARK`) VALUES (18, 'layout', '页面布局');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (1, 'bucket-name', '云存储服务名称', 'upyun');
INSERT INTO STORAGE_CONFIG (`ID`, `k`, `TITLE`, `TYPE`) VALUES (2, 'username', '操作员名称', 'upyun');

View File

@@ -1 +0,0 @@
.el-menu[data-v-d26ac70e],.el-row[data-v-d26ac70e]{height:100vh}

View File

@@ -0,0 +1 @@
.el-menu[data-v-7f233ce7],.el-row[data-v-7f233ce7]{height:100vh}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title></title><link href=/css/adminIndex.9c87dd59.css rel=prefetch><link href=/css/install.b4e8b552.css rel=prefetch><link href=/js/adminIndex.f735b8ee.js rel=prefetch><link href=/js/dplayer.acc587f7.js rel=prefetch><link href=/js/install.6a075002.js rel=prefetch><link href=/css/app.a2e3ef88.css rel=preload as=style><link href=/css/chunk-vendors.6ed6dc12.css rel=preload as=style><link href=/js/app.9d145c66.js rel=preload as=script><link href=/js/chunk-vendors.1f42ad6f.js rel=preload as=script><link href=/css/chunk-vendors.6ed6dc12.css rel=stylesheet><link href=/css/app.a2e3ef88.css rel=stylesheet></head><body><noscript><strong>We're sorry but zfile doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.1f42ad6f.js></script><script src=/js/app.9d145c66.js></script></body></html>
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title></title><link href=/css/adminIndex.a8c53261.css rel=prefetch><link href=/css/install.b4e8b552.css rel=prefetch><link href=/js/adminIndex.0916d17e.js rel=prefetch><link href=/js/dplayer.acc587f7.js rel=prefetch><link href=/js/install.0f6d1155.js rel=prefetch><link href=/css/app.fffbf4d6.css rel=preload as=style><link href=/css/chunk-vendors.cb63319e.css rel=preload as=style><link href=/js/app.b328f663.js rel=preload as=script><link href=/js/chunk-vendors.d1dab075.js rel=preload as=script><link href=/css/chunk-vendors.cb63319e.css rel=stylesheet><link href=/css/app.fffbf4d6.css rel=stylesheet></head><body><noscript><strong>We're sorry but zfile doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.d1dab075.js></script><script src=/js/app.b328f663.js></script></body></html>

View File

@@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["adminIndex"],{"366e":function(t,e,i){"use strict";var a=i("479f"),s=i.n(a);s.a},"479f":function(t,e,i){},adf4:function(t,e,i){"use strict";i.r(e);var a=function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("el-row",[i("el-col",{attrs:{span:3}},[i("el-menu",{staticClass:"el-menu-vertical-demo",attrs:{"default-active":"/admin"!==this.$route.path?this.$route.path:"/admin/site",router:!0}},[i("el-menu-item",{attrs:{index:"/admin/site"}},[i("i",{staticClass:"el-icon-setting"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("基本设置")])]),i("el-menu-item",{attrs:{index:"/admin/view"}},[i("i",{staticClass:"el-icon-view"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("显示设置")])]),i("el-menu-item",{attrs:{index:"/admin/storage"}},[i("i",{staticClass:"el-icon-s-operation"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("存储策略")])]),i("el-menu-item",{attrs:{index:"/admin/password"}},[i("i",{staticClass:"el-icon-key"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("修改密码")])]),i("el-menu-item",{attrs:{index:"/admin/cache"}},[i("i",{staticClass:"el-icon-collection"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("缓存管理")])]),i("el-menu-item",{attrs:{index:"/admin/api"}},[i("i",{staticClass:"el-icon-document"}),i("span",{attrs:{slot:"title"},slot:"title"},[t._v("API 文档")])])],1)],1),i("el-col",{attrs:{span:16}},[i("keep-alive",{attrs:{exclude:"CacheManager,SiteSetting"}},[i("router-view")],1)],1)],1)},s=[],n={name:"Index",data:function(){return{active:"/admin/storage"}}},l=n,o=(i("366e"),i("2877")),r=Object(o["a"])(l,a,s,!1,null,"7f233ce7",null);e["default"]=r.exports}}]);

View File

@@ -1 +0,0 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["adminIndex"],{"197f":function(t,e,a){"use strict";var i=a("9e7d"),s=a.n(i);s.a},"9e7d":function(t,e,a){},adf4:function(t,e,a){"use strict";a.r(e);var i=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("el-row",[a("el-col",{attrs:{span:3}},[a("el-menu",{staticClass:"el-menu-vertical-demo",attrs:{"default-active":"/admin"!==this.$route.path?this.$route.path:"/admin/site",router:!0}},[a("el-menu-item",{attrs:{index:"/admin/site"}},[a("i",{staticClass:"el-icon-setting"}),a("span",{attrs:{slot:"title"},slot:"title"},[t._v("站点设置")])]),a("el-menu-item",{attrs:{index:"/admin/storage"}},[a("i",{staticClass:"el-icon-s-operation"}),a("span",{attrs:{slot:"title"},slot:"title"},[t._v("存储策略")])]),a("el-menu-item",{attrs:{index:"/admin/password"}},[a("i",{staticClass:"el-icon-key"}),a("span",{attrs:{slot:"title"},slot:"title"},[t._v("修改密码")])]),a("el-menu-item",{attrs:{index:"/admin/cache"}},[a("i",{staticClass:"el-icon-collection"}),a("span",{attrs:{slot:"title"},slot:"title"},[t._v("缓存管理")])]),a("el-menu-item",{attrs:{index:"/admin/api"}},[a("i",{staticClass:"el-icon-document"}),a("span",{attrs:{slot:"title"},slot:"title"},[t._v("API 文档")])])],1)],1),a("el-col",{attrs:{span:16}},[a("keep-alive",{attrs:{exclude:"CacheManager,SiteSetting"}},[a("router-view")],1)],1)],1)},s=[],n={name:"Index",data:function(){return{active:"/admin/storage"}}},l=n,o=(a("197f"),a("2877")),r=Object(o["a"])(l,i,s,!1,null,"d26ac70e",null);e["default"]=r.exports}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long