完善目录文件列表;封装接口请求方法

This commit is contained in:
LittleBoy 2022-05-07 09:37:17 +08:00
parent 9220d88183
commit bb4e78ef97
17 changed files with 493 additions and 88 deletions

81
README.md Normal file
View File

@ -0,0 +1,81 @@
## 六 天牛网盘
### 6.1 数据字典
#### 用户信息
#### 文件信息
编号、用户编号、文件名、目录编号 、类型、大小、位置、创建时间、状态、hash
#### 目录信息
编号、用户编号、目录名称、上级目录编号、目录路径、创建时间、状态
#### 分享信息
编号、用户编号、分享的数据编号、分类类型(file|folder)、提取码、分享有效期、状态
### 6.2 技术架构
```shell
# 安装前端ui框架
npm i element-plus @element-plus/icons-vue less less-loader
```
### 6.3 后端项目
```yaml
# 应用名称
spring:
application:
name: Driver
# 数据库
datasource:
name: defaultDataSource
url: jdbc:mysql://localhost:3306/net_driver?serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
# 添加druid数据库连接池
type: com.alibaba.druid.pool.DruidDataSource
#数据源配置
druid:
max-active: 1000
initial-size: 10
max-wait: 1000
min-idle: 10
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
max-pool-prepared-statement-per-connection-size: 0
#监控
stat-view-servlet:
url-pattern: /druid/*
reset-enable: false
login-username: admin
login-password: admin
allow: 127.0.0.1
# 是否启用
enabled: true
web-stat-filter:
url-pattern: /*
exclusions: /druid/*,*.js,*.css,*.html,*.png,*.jpg
# redis缓存
redis:
database: 1
# 应用服务 WEB 访问端口
server:
port: 8080
# Actuator Web 访问端口
#management.server.port=8081
#management.endpoints.jmx.exposure.include=*
#management.endpoints.web.exposure.include=*
#management.endpoint.health.show-details=always
```

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -21,10 +21,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-amqp</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-amqp</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
@ -74,11 +74,17 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.amqp</groupId>-->
<!-- <artifactId>spring-rabbit-test</artifactId>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- swagger 文档-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.amqp</groupId>-->
<!-- <artifactId>spring-rabbit-test</artifactId>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
</dependencies>
<dependencyManagement>

View File

@ -2,6 +2,7 @@ package xyz.longicorn.driver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@SpringBootApplication
public class DriverApplication {

View File

@ -1,5 +1,8 @@
package xyz.longicorn.driver.config;
import lombok.Data;
@Data
public class BizException extends RuntimeException {
private int code;

View File

@ -0,0 +1,80 @@
package xyz.longicorn.driver.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;
@Configuration
@EnableOpenApi
public class SwaggerConfiguration {
// 创建api文档信息
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("xyz.longicorn.driver.controller"))
.paths(PathSelectors.any())
.build();
}
// API的信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("天牛网盘 API文档").description("天牛网盘 API文档")
.contact(new Contact("老王", "https://driver.longicorn.xyz/documents", "api@longicorn.xyz"))
.version("1.0").build();
}
// 解决swagger nullpointer
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
}

View File

@ -1,10 +1,12 @@
package xyz.longicorn.driver.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
@ -13,7 +15,9 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//映射static路径的请求到static目录下
// registry.addResourceHandler("/static/**")
// .addResourceLocations("classpath:/static/");
}
@Override

View File

@ -1,8 +1,13 @@
package xyz.longicorn.driver.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import xyz.longicorn.driver.dto.ApiResult;
import xyz.longicorn.driver.pojo.FolderInfo;
import xyz.longicorn.driver.service.FolderService;
@ -11,13 +16,21 @@ import java.util.List;
@RestController
@RequestMapping("/api/folder")
@Api("目录操作")
public class FolderController {
@Resource
private FolderService folderService;
@RequestMapping("/list")
// 查询相应目录下的所有文件()信息
public List<FolderInfo> listFolder(@RequestParam(required = false, defaultValue = "/") String folderPath) {
return folderService.listFolder(1, folderPath);
//接口文档的名称
@ApiOperation(value = "查询目录信息", notes = "查询相应目录下的所有文件(夹)信息",httpMethod = "GET")
public ApiResult listFolder(@RequestParam(required = false, defaultValue = "/") String folderPath) {
return ApiResult.success(folderService.listFolder(1, folderPath));
}
// 创建目录
@ApiOperation(value = "创建目录", notes = "创建目录1")
public FolderInfo create(String parent, String name) {
return null;
}
}

View File

@ -0,0 +1,34 @@
package xyz.longicorn.driver.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import xyz.longicorn.driver.config.BizException;
import java.io.Serializable;
import java.util.Date;
@Data
@Accessors(chain = true)
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class ApiResult implements Serializable {
private int code;
private String message;
private Object data;
public static ApiResult success(Object data) {
return new ApiResult(0, "success", data);
}
public static ApiResult error(int code, String message) {
return new ApiResult(code, message, null);
}
public static ApiResult error(BizException e) {
return new ApiResult(e.getCode(), e.getMessage(), null);
}
}

View File

@ -40,6 +40,14 @@ spring:
# redis缓存
redis:
database: 1
mvc:
pathmatch:
# 因为Springfox使用的路径匹配是基于AntPathMatcher的而Spring Boot 2.6.X使用的是PathPatternMatcher。
matching-strategy: ant_path_matcher
springfox:
documentation:
enabled: true
# 应用服务 WEB 访问端口
server:
port: 8080

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<title>天牛网盘</title>
</head>
<body>
<div id="app"></div>

109
web/package-lock.json generated
View File

@ -12,6 +12,7 @@
"element-plus": "^2.1.11",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"qs": "^6.10.3",
"vue": "^3.2.25",
"vue-router": "^4.0.15"
},
@ -514,6 +515,15 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"peer": true
},
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dependencies": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001336",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001336.tgz",
@ -1079,8 +1089,17 @@
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1"
}
},
"node_modules/glob-to-regexp": {
"version": "0.4.1",
@ -1097,7 +1116,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
@ -1114,6 +1132,14 @@
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -1377,6 +1403,11 @@
"resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.1.2.tgz",
"integrity": "sha512-scX83plWJXYH1J4+BhAuIHadROzxX0UBF3+HuZNY2Ks8BciE7tSTQ+5JhTsvzjaO0/EJdm4JBGrfObKxFf3Png=="
},
"node_modules/object-inspect": {
"version": "1.12.0",
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.0.tgz",
"integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
},
"node_modules/parse-node-version": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
@ -1433,6 +1464,17 @@
"node": ">=6"
}
},
"node_modules/qs": {
"version": "6.10.3",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz",
"integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
"dependencies": {
"side-channel": "^1.0.4"
},
"engines": {
"node": ">=0.6"
}
},
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
@ -1521,6 +1563,16 @@
"randombytes": "^2.1.0"
}
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
@ -2264,6 +2316,15 @@
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"peer": true
},
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"caniuse-lite": {
"version": "1.0.30001336",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001336.tgz",
@ -2607,8 +2668,17 @@
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1"
}
},
"glob-to-regexp": {
"version": "0.4.1",
@ -2625,7 +2695,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
@ -2636,6 +2705,11 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"peer": true
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -2835,6 +2909,11 @@
"resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.1.2.tgz",
"integrity": "sha512-scX83plWJXYH1J4+BhAuIHadROzxX0UBF3+HuZNY2Ks8BciE7tSTQ+5JhTsvzjaO0/EJdm4JBGrfObKxFf3Png=="
},
"object-inspect": {
"version": "1.12.0",
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.0.tgz",
"integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
},
"parse-node-version": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
@ -2879,6 +2958,14 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"peer": true
},
"qs": {
"version": "6.10.3",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz",
"integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
"requires": {
"side-channel": "^1.0.4"
}
},
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
@ -2952,6 +3039,16 @@
"randombytes": "^2.1.0"
}
},
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"requires": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",

View File

@ -12,6 +12,7 @@
"element-plus": "^2.1.11",
"less": "^4.1.2",
"less-loader": "^10.2.0",
"qs": "^6.10.3",
"vue": "^3.2.25",
"vue-router": "^4.0.15"
},

View File

@ -1,80 +1,55 @@
<script>
import FileIcon from "./components/FileIcon.vue";
import { ElMessage } from 'element-plus'
import {dayjs, ElMessage} from 'element-plus'
import api from "./service/api";
import qs from "qs";
export default {
data() {
return {
currentActiveIndex: "all",
display: 'block',
fileData: [
{
id: 1,
name: "我的文档",
type: "folder",
size: 0,
createTime: "2022-05-05 15:32:00"
},
{
id: 2,
name: "我的相册",
type: "folder",
size: 0,
createTime: "2022-05-05 15:32:00"
},
{
id: 3,
name: "我的视频",
type: "folder",
size: 0,
createTime: "2022-05-05 15:32:00"
},
{
id: 4,
name: "我的APP",
type: "folder",
size: 0,
createTime: "2022-05-05 15:32:00"
},
{
id: 5,
name: "weixin.logo.png",
path: "/src/assets/icons/mp.weixin.qq.com.png",
type: "png",
size: 10240,
createTime: "2022-05-05 15:38:00"
},
{
id: 6,
name: "QQ_Setup.exe",
type: "exe",
size: 10240,
createTime: "2022-05-05 15:38:00"
}
]
fileData: []
};
},
components: { FileIcon },
components: {FileIcon},
mounted() {
// window.addEventListener('popstate',()=>console.log(location.href))
window.addEventListener('hashchange', this.handlePathChange) //
this.handlePathChange();
},
unmounted() {
window.removeEventListener('hashchange', this.handlePathChange); //
},
methods: {
//
async loadFileByPath(path = '/') {
//
try {
const list = await api.folder.list(path);
this.fileData = list;
} catch (e) {
ElMessage.error(e.message)
}
},
handlePathChange() {
console.log(location.href)
const hash = location.hash;
const params = qs.parse(hash.substr(2))
this.loadFileByPath(params.path || '/') // 使
},
formatDate(time) {
return dayjs(time).format('MM-DD');
},
showFile(file) {
if (file.type != 'folder') {
ElMessage('暂不支持此文件的预览');
return;
}
console.log(file)
this.loadFileByPath(file.path)
// if (file.type != 'folder') {
// ElMessage('');
// return;
// }
// console.log(file)
// window.history.pushState({},null,'/show?path=' + file.name)
location.hash = '/show?path=' + file.name
location.hash = '?path=' + file.path
}
}
}
@ -82,7 +57,7 @@ export default {
<template>
<el-container>
<el-aside class="pan-left-aside">
<h1>牛牛的网盘</h1>
<div class="logo-block">牛牛的网盘</div>
<el-menu :default-active="currentActiveIndex" class="pan-left-menu">
<el-menu-item index="all">
<span>所有文件</span>
@ -110,7 +85,7 @@ export default {
<span class="el-dropdown-link">
张三
<el-icon class="el-icon--right">
<arrow-down />
<arrow-down/>
</el-icon>
</span>
<template #dropdown>
@ -125,23 +100,24 @@ export default {
</ul>
</el-header>
<el-main>
<el-button @click="display = (display == 'block' ? 'list' : 'block')">{{ (display == 'block' ? 'list' : 'block') }}
<el-button @click="display = (display == 'block' ? 'list' : 'block')">
{{ (display == 'block' ? 'list' : 'block') }}
</el-button>
<div class="display-type-list" v-if="display == 'list'">
<el-table :data="fileData" style="width: 100%">
<el-table-column type="selection" />
<el-table-column type="selection"/>
<el-table-column label="名称">
<!-- 自定义单元格内容 -->
<template #default="file">
<div>
<FileIcon :file="file.row" style="width:20px" />
<FileIcon :file="file.row" style="width:20px"/>
<span>{{ file.row.name }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="type" label="类型" width="200" />
<el-table-column prop="size" label="大小" width="200" />
<el-table-column prop="createTime" label="创建时间" width="200" />
<el-table-column prop="type" label="类型" width="200"/>
<el-table-column prop="size" label="大小" width="200"/>
<el-table-column prop="createTime" label="创建时间" width="200"/>
</el-table>
</div>
<div class="display-type-block" v-else>
@ -149,9 +125,10 @@ export default {
<el-col :xs="12" :sm="6" :md="4" :lg="3" :xl="2" v-for="(file, index) in fileData" :key="index">
<div class="file-block-item" @click="showFile(file)">
<div>
<FileIcon :file="file" style="width:90%" />
<FileIcon :file="file" style="width:90%"/>
</div>
<div>{{ file.name }}</div>
<div class="file-name">{{ file.name }}</div>
<div class="file-info">{{ formatDate(file.createTime) }}</div>
</div>
</el-col>
</el-row>
@ -160,13 +137,20 @@ export default {
</el-container>
</el-container>
</template>
<style lang="less">
* {
margin: 0;
padding: 0;
}
.logo-block {
line-height: 60px;
text-align: center;
background-color: var(--el-color-primary);
color: #fff;
font-size: 24px;
}
.pan-left-menu {
border-right: none;
}
@ -190,9 +174,26 @@ export default {
float: left;
}
//
.file-block-item {
margin: 10px 0;
text-align: center;
padding: 10px;
cursor: pointer;
border-radius: 5px;
&:hover {}
&:hover {
background-color: var(--el-color-primary-light-8);
}
.file-name {
font-size: 16px;
}
.file-info {
margin-top: 3px;
font-size: 12px;
color: #999;
}
}
</style>

View File

@ -23,7 +23,7 @@ export default {
}
},
mounted(){
const type = this.file.type.toLowerCase(); //
const type = this.file.type?.toLowerCase(); //
if(['png','jpg','jpeg','gif','webp'].includes(type)){
this.currentSrc = this.file.path || UnknownIcon; //
}else if(type == 'exe') {

69
web/src/service/api.js Normal file
View File

@ -0,0 +1,69 @@
const API_PATH = "http://localhost:8080"
/**
*
* @param api
* @param {'GET'|'POST'|string} method
* @param postData
*/
function request(api, method = 'GET', postData = {}) {
//return fetch(API_PATH + api).then(res => res.json());
let options = {
method
};
if (method.toUpperCase() == 'GET') {
// post => 'key=value&key1=value1'
const params = [];
for (let key in postData) {
params.push(`${key}=${postData[key]}`);
}
api += (api.includes('?') ? '&' : '?') + params.join('&');
} else {
options = {
method,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(postData) // 参数
}
}
return new Promise((resolve, reject) => {
/**
*
* @param {ApiResult} result
*/
const processResult = result => {
if (result.code === 0) { // 判断响应码是否正常
resolve(result.data)
} else { // 有异常 直接抛出错误
reject(new Error(result.message))
}
}
fetch(API_PATH + api, options).then(res => res.json())
.then(processResult)
.catch(e => {
reject(e);
})
});
}
export default {
user: {
login() {
},
signup() {
}
},
folder: {
/**
* 列出所有的子文件列表
* @param path
* @returns {Promise<Array>}
*/
list(folderPath = '/') {
return request(`/api/folder/list`, 'GET', {folderPath})
}
}
}

1
web/src/service/type.d.ts vendored Normal file
View File

@ -0,0 +1 @@
declare type ApiResult = { code: number, message: string, data: any }