完成目录创建

This commit is contained in:
LittleBoy 2022-05-09 10:23:07 +08:00
parent bb4e78ef97
commit 6600a6e697
21 changed files with 862 additions and 133 deletions

124
.idea/uiDesigner.xml generated Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@ -79,3 +79,9 @@ server:
```
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request

View File

@ -4,15 +4,16 @@ 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 org.springframework.web.bind.annotation.*;
import xyz.longicorn.driver.dto.ApiResult;
import xyz.longicorn.driver.dto.FileItem;
import xyz.longicorn.driver.dto.FolderDto;
import xyz.longicorn.driver.pojo.FolderInfo;
import xyz.longicorn.driver.service.FolderService;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/folder")
@ -23,14 +24,20 @@ public class FolderController {
@RequestMapping("/list")
//接口文档的名称
@ApiOperation(value = "查询目录信息", notes = "查询相应目录下的所有文件(夹)信息",httpMethod = "GET")
@ApiOperation(value = "查询目录信息", notes = "查询相应目录下的所有文件(夹)信息", httpMethod = "GET")
public ApiResult listFolder(@RequestParam(required = false, defaultValue = "/") String folderPath) {
return ApiResult.success(folderService.listFolder(1, folderPath));
return ApiResult.success(
folderService.listFolder(1, folderPath)
);
}
// 创建目录
@PostMapping("/create")
@ApiOperation(value = "创建目录", notes = "创建目录1")
public FolderInfo create(String parent, String name) {
return null;
public ApiResult create(@RequestBody FolderDto f) {
String parent = f.getParent(), name = f.getName();
return ApiResult.success(
folderService.create(1, parent, name)
);
}
}

View File

@ -0,0 +1,10 @@
package xyz.longicorn.driver.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import xyz.longicorn.driver.pojo.FileInfo;
import xyz.longicorn.driver.pojo.FolderInfo;
@Mapper
public interface FileInfoMapper extends BaseMapper<FileInfo> {
}

View File

@ -0,0 +1,69 @@
package xyz.longicorn.driver.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import xyz.longicorn.driver.pojo.FileInfo;
import xyz.longicorn.driver.pojo.FolderInfo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
* 文件项 可以是文件也可以是目录
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class FileItem {
private Long id;
private String name;
private Integer size;
private String path;
private Date createTime;
private Date updateTime;
private String type;
public static List<FileItem> buildFolderList(List<FolderInfo> list) {
List<FileItem> listItems = new ArrayList<>();
list.forEach(f -> listItems.add(build(f)));
return listItems;
}
public static FileItem build(FolderInfo f) {
return new FileItem()
.setCreateTime(f.getCreateTime())
.setId(f.getId())
.setName(f.getName())
.setSize(0)
.setType("folder")
.setPath(f.getPath())
.setUpdateTime(f.getUpdateTime());
}
public static List<FileItem> buildFileList(List<FileInfo> list) {
List<FileItem> listItems = new ArrayList<>();
list.forEach(f -> listItems.add(build(f)));
return listItems;
}
/**
* 将文件转成fileItem
* @param f
* @return
*/
public static FileItem build(FileInfo f) {
return new FileItem()
.setCreateTime(f.getCreateTime())
.setId(f.getId())
.setName(f.getName())
.setSize(f.getSize())
.setType(f.getType())
.setPath(f.getPath())
.setUpdateTime(f.getUpdateTime());
}
}

View File

@ -0,0 +1,9 @@
package xyz.longicorn.driver.dto;
import lombok.Data;
@Data
public class FolderDto {
private String parent;
private String name;
}

View File

@ -0,0 +1,32 @@
package xyz.longicorn.driver.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class FileInfo implements Serializable {
private Long id;
private Long uid;
private String name;
private String hash;
private Long folderId;
private String type;
private Integer size;
private String path;
private Date createTime;
private Date updateTime;
private Long status;
}

View File

@ -0,0 +1,26 @@
package xyz.longicorn.driver.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.longicorn.driver.dao.FileInfoMapper;
import xyz.longicorn.driver.pojo.FileInfo;
import java.util.List;
@Service
public class FileService extends ServiceImpl<FileInfoMapper, FileInfo> {
/**
* 查询了目录下的文件列表集合
* @param uid
* @param folderId
* @return
*/
public List<FileInfo> listByFolderId(int uid,long folderId){
QueryWrapper q = new QueryWrapper();
q.eq("uid",uid);
q.eq("folder_id",folderId);
q.eq("status",1); // TODO 枚举
return this.list(q);
}
}

View File

@ -5,12 +5,26 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.longicorn.driver.config.BizException;
import xyz.longicorn.driver.dao.FolderInfoMapper;
import xyz.longicorn.driver.dto.FileItem;
import xyz.longicorn.driver.pojo.FileInfo;
import xyz.longicorn.driver.pojo.FolderInfo;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Service
public class FolderService extends ServiceImpl<FolderInfoMapper, FolderInfo> {
@Resource
private FileService fileService;
/**
* 根据路径查询目录信息
*
* @param uid
* @param path
* @return
*/
public FolderInfo getByPath(int uid, String path) {
QueryWrapper q = new QueryWrapper();
q.eq("uid", uid);
@ -18,7 +32,23 @@ public class FolderService extends ServiceImpl<FolderInfoMapper, FolderInfo> {
return this.getOne(q);
}
public List<FolderInfo> listFolder(int uid, String path) {
/**
* 根据目录的名称查询信息
*
* @param uid
* @param name
* @param parentId
* @return
*/
public FolderInfo getByNameAndParent(int uid, String name, long parentId) {
QueryWrapper q = new QueryWrapper();
q.eq("uid", uid);
q.eq("name", name);
q.eq("parent_id", parentId);
return this.getOne(q);
}
public List<FileItem> listFolder(int uid, String path) {
long parentId = 0; // 默认查询根目录
// 路径为空或者 / 表示根目录
if (path != null && !path.equals("/")) {
@ -29,12 +59,34 @@ public class FolderService extends ServiceImpl<FolderInfoMapper, FolderInfo> {
QueryWrapper q = new QueryWrapper();
q.eq("parent_id", parentId); // 设置查询条件
q.eq("uid", uid);
return this.list(q);
// 查询目录集合
final List<FolderInfo> folderList = this.list(q);
List<FileItem> fsList = FileItem.buildFolderList(folderList); // 直接将folder集合转成fileitem集合
final List<FileInfo> fileInfos = fileService.listByFolderId(uid, parentId);//文件信息
fsList.addAll(FileItem.buildFileList(fileInfos)); // 合并目录和文件
return fsList;
}
public FolderInfo create() {
// 验证是否存在相同路径的文件夹
// ifxxx) throw new RuntimeException("创建失败,名称相同l")
return null;
public FolderInfo create(int uid, String parent, String name) {
long parentId = 0; // 默认根目录
if (parent != null && !parent.equals("/")) {
FolderInfo f = this.getByPath(uid, parent); // 根据路径查询目录信息
if (f == null) throw BizException.create("父目录不存在"); // 没有查询到信息
parentId = f.getId(); // 设置查询的父目录id
}
// 根据目录查询是否存在
FolderInfo myFolderInfo = this.getByNameAndParent(uid, name, parentId);//根据名称查询目录信息
if (myFolderInfo != null) {
throw BizException.create("文件夹已经存在了");
}
FolderInfo fNew = new FolderInfo();
fNew.setUid(uid);
fNew.setName(name);
fNew.setParentId(parentId);
fNew.setPath(parent + "/" + name);
;
return this.save(fNew) ? fNew : null;
}
}

View File

@ -12,4 +12,20 @@ create table folder_info
index ix_name (name),
index ix_path (path),
index ix_uid (uid)
);
# 编号、用户编号、文件名、目录编号 、类型、大小、位置、创建时间、状态、hash
create table file_info(
id bigint(20) not null primary key auto_increment,
uid int(10) not null,
name varchar(50) not null,
hash varchar(32) not null comment '文件MD5特征码',
folder_id bigint(20) null default 0 comment '所在目录的编号,0表示根目录',
type varchar(5) null,
size int null default 0,
path varchar(500) not null comment '文件的物理存储位置,可以是本地路径也可以是一个网址', -- file://d:/a/b/c.txt http://
create_time datetime default current_timestamp,
update_time datetime on update current_timestamp,
status tinyint(1) default 1,
index ix_file_name(name)
);

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>天牛网盘</title>
</head>

35
web/package-lock.json generated
View File

@ -14,7 +14,8 @@
"less-loader": "^10.2.0",
"qs": "^6.10.3",
"vue": "^3.2.25",
"vue-router": "^4.0.15"
"vue-router": "^4.0.15",
"vue-simple-context-menu": "^4.0.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.3.1",
@ -539,6 +540,14 @@
"node": ">=6.0"
}
},
"node_modules/click-outside-vue3": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/click-outside-vue3/-/click-outside-vue3-4.0.1.tgz",
"integrity": "sha512-sbplNecrup5oGqA3o4bo8XmvHRT6q9fvw21Z67aDbTqB9M6LF7CuYLTlLvNtOgKU6W3zst5H5zJuEh4auqA34g==",
"engines": {
"node": ">=6"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
@ -1799,6 +1808,17 @@
"vue": "^3.2.0"
}
},
"node_modules/vue-simple-context-menu": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/vue-simple-context-menu/-/vue-simple-context-menu-4.0.2.tgz",
"integrity": "sha512-3DcKuNtEZkh6Gi70NIODTXvPlHnVJgyg3ejXNqVHFWTRWSGoZsfeqZKAfSRANAPLshEhUGcVzT4kTPrXvC5WNQ==",
"dependencies": {
"click-outside-vue3": "^4.0.1"
},
"peerDependencies": {
"vue": "^3.2.31"
}
},
"node_modules/watchpack": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.3.1.tgz",
@ -2337,6 +2357,11 @@
"integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
"peer": true
},
"click-outside-vue3": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/click-outside-vue3/-/click-outside-vue3-4.0.1.tgz",
"integrity": "sha512-sbplNecrup5oGqA3o4bo8XmvHRT6q9fvw21Z67aDbTqB9M6LF7CuYLTlLvNtOgKU6W3zst5H5zJuEh4auqA34g=="
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
@ -3193,6 +3218,14 @@
"@vue/devtools-api": "^6.0.0"
}
},
"vue-simple-context-menu": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/vue-simple-context-menu/-/vue-simple-context-menu-4.0.2.tgz",
"integrity": "sha512-3DcKuNtEZkh6Gi70NIODTXvPlHnVJgyg3ejXNqVHFWTRWSGoZsfeqZKAfSRANAPLshEhUGcVzT4kTPrXvC5WNQ==",
"requires": {
"click-outside-vue3": "^4.0.1"
}
},
"watchpack": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.3.1.tgz",

View File

@ -14,7 +14,8 @@
"less-loader": "^10.2.0",
"qs": "^6.10.3",
"vue": "^3.2.25",
"vue-router": "^4.0.15"
"vue-router": "^4.0.15",
"vue-simple-context-menu": "^4.0.2"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.3.1",

1
web/public/logo.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1651895924070" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2966" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000"><defs><style type="text/css"></style></defs><path d="M549.766 97.925c19.974 4.609 50.703 35.339 62.995 55.312 35.339-13.828 36.875 41.484 46.094 55.312 23.047-16.901 46.094-35.339 46.094-55.312 0-21.51-30.729-35.339-30.729-41.484 0-12.292 38.411-12.292 41.484-12.292 50.703 0 106.016 39.948 106.016 96.797 0 27.656-9.219 41.484-33.802 70.677h32.266c21.51 0 27.656-3.073 55.312 7.682C923.125 294.591 960 348.367 960 389.852c0 3.073 0 9.219-1.536 13.828-4.609 3.073-12.292 3.073-16.901 4.609-15.365 1.536-32.266 6.146-47.63 7.682-47.63 0-50.703 0-53.776-1.536-1.536 1.536-1.536 0-1.536 4.609 0 3.073 7.682 44.557 10.755 67.604 9.219 56.849 12.292 115.234 19.974 173.62 1.536 7.682 7.682 15.365 9.219 23.047 3.073 13.828 6.146 27.656 6.146 39.948 0 153.646-245.833 208.958-321.119 208.958h-86.042c-115.234-9.219-248.906-52.24-301.145-138.281-4.609-7.682-18.437-39.948-18.437-50.703v-36.875c3.073-16.901 7.682-33.802 21.51-50.703v-84.505l12.292-132.135c-12.292 1.536-33.802 1.536-38.411 1.536-21.51 0-38.411-3.073-61.458-6.146-7.682-1.536-18.437-3.073-24.583-6.146-4.609-1.536-3.073-12.292-3.073-13.828 0-44.557 44.557-107.552 98.333-119.844 4.609-1.536 13.828-1.536 19.974-3.073l41.484-1.536c-13.828-10.755-36.875-46.094-36.875-59.922v-29.193c13.828-58.385 62.995-82.969 106.016-82.969 1.536 0 41.484 0 41.484 12.292 0 6.146-30.729 19.974-30.729 41.484 0 1.536 6.146 32.266 16.901 32.266 3.073 0-1.536-3.073 3.073-3.073 3.073 0 32.266 10.755 36.875 10.755h12.292l3.073-3.073c-19.974-16.901-30.729-36.875-36.875-53.776 12.292 7.682 18.438 9.219 29.193 9.219 27.656 0 46.094-15.365 78.359-29.193 24.583-10.755 52.24-13.828 78.359-18.437-12.292-9.219-24.583-16.901-36.875-23.047l38.411-1.536c7.68 1.537 15.362 4.61 23.044 6.146z" p-id="2967"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,147 +1,360 @@
<script>
import {ArrowDown, Grid} from '@element-plus/icons-vue'
import FileIcon from "./components/FileIcon.vue";
import {dayjs, ElMessage} from 'element-plus'
import {dayjs, ElMessage, ElMessageBox} from 'element-plus'
import api from "./service/api";
import qs from "qs";
export default {
data() {
return {
currentActiveIndex: "all",
display: 'block',
fileData: []
/**
* @var {FileItem[]}
*/
fileData: [],
currentPath: '/',
fileMenuOption: [
{
name: '打开',
slug: 'open',
},
{
name: '下载',
slug: 'download',
},
{
name: '分享',
slug: 'share',
},
{
type: 'divider',
},
{
name: '复制',
slug: 'copy',
},
{
name: '移动',
slug: 'move',
},
{
name: '重命名',
slug: 'rename',
},
{
type: 'divider',
},
{
name: '删除',
slug: 'delete',
},
],
createFolder: {
visible: false,
value: '',
loading: false,
message: ''
},
};
},
components: {FileIcon},
computed: {
currentPathList() {
if (this.currentPath == '/') return []
const arr = this.currentPath.replace(/^\//, '').split('/');
const pathList = [], last = arr.pop();
let prefix = '';
arr.forEach(name => {
prefix += '/' + name;
pathList.push({name: name, path: prefix})
})
pathList.push({name: last, path: null})
return pathList;
}
},
components: {FileIcon, ArrowDown, Grid},
mounted() {
// window.addEventListener('popstate',()=>console.log(location.href))
window.addEventListener('hashchange', this.handlePathChange) //
this.handlePathChange();
window.addEventListener('hashchange', this.handleHashChange) //
this.handleHashChange();
},
unmounted() {
window.removeEventListener('hashchange', this.handlePathChange); //
window.removeEventListener('hashchange', this.handleHashChange); //
},
methods: {
//
async loadFileByPath(path = '/') {
this.currentPath = path //
//
try {
this.fileData = [];
const list = await api.folder.list(path);
this.fileData = list;
} catch (e) {
ElMessage.error(e.message)
}
},
handlePathChange() {
//
getCurrentPath() {
const hash = location.hash;
const params = qs.parse(hash.substr(2))
this.loadFileByPath(params.path || '/') // 使
return params.path || '/';
},
formatDate(time) {
return dayjs(time).format('MM-DD');
//
handleHashChange() {
this.loadFileByPath(this.getCurrentPath()) // 使
},
showFile(file) {
console.log(file)
this.loadFileByPath(file.path)
// if (file.type != 'folder') {
// ElMessage('');
// return;
// }
formatDate(time, format = 'MM-DD') {
return dayjs(time).format(format);
},
formatSize(a, b = 2) {
if (0 == a) return "0 B";
let c = 1024, d = b || 2, e = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
f = Math.floor(Math.log(a) / Math.log(c));
return parseFloat((a / Math.pow(c, f)).toFixed(d)) + " " + e[f];
},
showFile(file, e) {
console.log(e)
if (file.type != 'folder') {
console.log(this.$refs.fileIcon)
this.$refs.fileIcon?.showPreview(file);
return;
}
// this.loadFileByPath(file.path)
// console.log(file)
// window.history.pushState({},null,'/show?path=' + file.name)
location.hash = '?path=' + file.path
},
fileMenuClick(e) {
window.alert(JSON.stringify(e));
},
createFolderClick() {
ElMessageBox.prompt(
'', '新建文件夹',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
// inputPattern:/[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
inputValidator(value) {
return !!value;
},
inputErrorMessage: '必须填写文件夹名称',
inputPlaceholder: '请输入文件夹名称'
})
.then(({value}) => {
//
})
.catch()
},
async handleCreateFolder() {
this.createFolder.message = ''
if (!this.createFolder.value) {
this.createFolder.message = '请填写文件夹名称'
return;
}
//
this.createFolder.loading = true;
try {
await api.folder.create(this.getCurrentPath(),this.createFolder.value);
this.createFolder.visible = false;
this.handleHashChange();
} catch (e) {
this.createFolder.message = e.message;
}finally {
this.createFolder.loading = false // loading
}
}
}
}
</script>
<template>
<el-container>
<el-aside class="pan-left-aside">
<div class="logo-block">牛牛的网盘</div>
<el-menu :default-active="currentActiveIndex" class="pan-left-menu">
<el-menu-item index="all">
<span>所有文件</span>
</el-menu-item>
<el-menu-item index="最近上传">
<span>所有文件</span>
</el-menu-item>
<el-menu-item index="picture">
<span>我的图片</span>
</el-menu-item>
<el-menu-item index="document">
<span>我的文档</span>
</el-menu-item>
<el-menu-item index="video">
<span>我的视频</span>
</el-menu-item>
</el-menu>
</el-aside>
<div class="main-pan-app" @contextmenu="$refs.fileMenu.hideContextMenu">
<el-container>
<el-header class="pan-header">
<ul class="pan-header-user-right">
<li>帮助</li>
<li>
<el-dropdown>
<span class="el-dropdown-link">
张三
<el-icon class="el-icon--right">
<arrow-down/>
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>修改资料</el-dropdown-item>
<el-dropdown-item>登录日志查看</el-dropdown-item>
<el-dropdown-item>退出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</li>
</ul>
</el-header>
<el-main>
<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 label="名称">
<!-- 自定义单元格内容 -->
<template #default="file">
<div>
<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>
<el-aside class="pan-left-aside">
<div class="logo-block">
<svg class="logo-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1000" height="1000">
<path
d="M549.766 97.925c19.974 4.609 50.703 35.339 62.995 55.312 35.339-13.828 36.875 41.484 46.094 55.312 23.047-16.901 46.094-35.339 46.094-55.312 0-21.51-30.729-35.339-30.729-41.484 0-12.292 38.411-12.292 41.484-12.292 50.703 0 106.016 39.948 106.016 96.797 0 27.656-9.219 41.484-33.802 70.677h32.266c21.51 0 27.656-3.073 55.312 7.682C923.125 294.591 960 348.367 960 389.852c0 3.073 0 9.219-1.536 13.828-4.609 3.073-12.292 3.073-16.901 4.609-15.365 1.536-32.266 6.146-47.63 7.682-47.63 0-50.703 0-53.776-1.536-1.536 1.536-1.536 0-1.536 4.609 0 3.073 7.682 44.557 10.755 67.604 9.219 56.849 12.292 115.234 19.974 173.62 1.536 7.682 7.682 15.365 9.219 23.047 3.073 13.828 6.146 27.656 6.146 39.948 0 153.646-245.833 208.958-321.119 208.958h-86.042c-115.234-9.219-248.906-52.24-301.145-138.281-4.609-7.682-18.437-39.948-18.437-50.703v-36.875c3.073-16.901 7.682-33.802 21.51-50.703v-84.505l12.292-132.135c-12.292 1.536-33.802 1.536-38.411 1.536-21.51 0-38.411-3.073-61.458-6.146-7.682-1.536-18.437-3.073-24.583-6.146-4.609-1.536-3.073-12.292-3.073-13.828 0-44.557 44.557-107.552 98.333-119.844 4.609-1.536 13.828-1.536 19.974-3.073l41.484-1.536c-13.828-10.755-36.875-46.094-36.875-59.922v-29.193c13.828-58.385 62.995-82.969 106.016-82.969 1.536 0 41.484 0 41.484 12.292 0 6.146-30.729 19.974-30.729 41.484 0 1.536 6.146 32.266 16.901 32.266 3.073 0-1.536-3.073 3.073-3.073 3.073 0 32.266 10.755 36.875 10.755h12.292l3.073-3.073c-19.974-16.901-30.729-36.875-36.875-53.776 12.292 7.682 18.438 9.219 29.193 9.219 27.656 0 46.094-15.365 78.359-29.193 24.583-10.755 52.24-13.828 78.359-18.437-12.292-9.219-24.583-16.901-36.875-23.047l38.411-1.536c7.68 1.537 15.362 4.61 23.044 6.146z"
p-id="2967"></path>
</svg>
<span>牛牛的网盘</span>
</div>
<div class="display-type-block" v-else>
<el-row :gutter="20">
<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%"/>
<el-menu :default-active="currentActiveIndex" class="pan-left-menu">
<el-menu-item index="all">
<span>所有文件</span>
</el-menu-item>
<el-menu-item index="最近上传">
<span>所有文件</span>
</el-menu-item>
<el-menu-item index="picture">
<span>我的图片</span>
</el-menu-item>
<el-menu-item index="document">
<span>我的文档</span>
</el-menu-item>
<el-menu-item index="video">
<span>我的视频</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-container>
<el-header class="pan-header">
<ul class="pan-header-user-right">
<li>帮助</li>
<li>
<el-dropdown>
<div class="el-dropdown-link">
<el-avatar class="avatar" :size="30"
src="https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png"/>
<span class="username">张三</span>
<el-icon class="el-icon--right">
<arrow-down/>
</el-icon>
</div>
<div class="file-name">{{ file.name }}</div>
<div class="file-info">{{ formatDate(file.createTime) }}</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>修改资料</el-dropdown-item>
<el-dropdown-item>登录日志查看</el-dropdown-item>
<el-dropdown-item>退出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</li>
</ul>
</el-header>
<el-main>
<div class="d-flex">
<div class="left-tool-bar">
<el-dropdown>
<el-button size="default" round>上传</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>上传文件</el-dropdown-item>
<el-dropdown-item>上传文件夹</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-button @click="createFolder.visible = true" style="margin-left: 10px" size="default"
round
type="primary">新建文件夹
</el-button>
</div>
</div>
<div style="display: flex;padding: 10px 0;line-height: 30px;">
<!-- 当前路径 -->
<div style="flex:1;display: flex">
<div v-if="currentPath === '/'" style="font-weight: 700;font-size: 14px;">全部文件</div>
<div v-else>
<el-breadcrumb separator="/" style="line-height: 30px">
<el-breadcrumb-item>
<a href="#?path=/">全部文件</a>
</el-breadcrumb-item>
<el-breadcrumb-item v-for="p in currentPathList" :key="p.path">
<a v-if="p.path" :href="'#?path=' + p.path">{{ p.name }}</a>
<span v-else>{{ p.name }}</span>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
</el-col>
</el-row>
</div>
</el-main>
</div>
<div class="d-flex">
<span
style="margin-right: 10px;color:#999;font-size: 12px;">已全部加载{{
fileData.length
}}</span>
<el-radio-group v-model="display" size="small">
<el-radio-button label="block">
<el-icon :size="16">
<svg class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path
d="M384 128H213.333333a85.333333 85.333333 0 0 0-85.333333 85.333333v170.666667a85.333333 85.333333 0 0 0 85.333333 85.333333h170.666667a85.333333 85.333333 0 0 0 85.333333-85.333333V213.333333a85.333333 85.333333 0 0 0-85.333333-85.333333zM810.666667 128h-170.666667a85.333333 85.333333 0 0 0-85.333333 85.333333v170.666667a85.333333 85.333333 0 0 0 85.333333 85.333333h170.666667a85.333333 85.333333 0 0 0 85.333333-85.333333V213.333333a85.333333 85.333333 0 0 0-85.333333-85.333333zM384 554.666667H213.333333a85.333333 85.333333 0 0 0-85.333333 85.333333v170.666667a85.333333 85.333333 0 0 0 85.333333 85.333333h170.666667a85.333333 85.333333 0 0 0 85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 0-85.333333-85.333333zM810.666667 554.666667h-170.666667a85.333333 85.333333 0 0 0-85.333333 85.333333v170.666667a85.333333 85.333333 0 0 0 85.333333 85.333333h170.666667a85.333333 85.333333 0 0 0 85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 0-85.333333-85.333333z"
p-id="2910"></path>
</svg>
</el-icon>
</el-radio-button>
<el-radio-button label="list">
<el-icon :size="16">
<svg class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path
d="M146.285714 749.714286v109.714285c0 9.728-8.557714 18.285714-18.285714 18.285715h-109.714286a18.797714 18.797714 0 0 1-18.285714-18.285715v-109.714285c0-9.728 8.557714-18.285714 18.285714-18.285715h109.714286c9.728 0 18.285714 8.557714 18.285714 18.285715z m0-219.428572v109.714286c0 9.728-8.557714 18.285714-18.285714 18.285714h-109.714286a18.797714 18.797714 0 0 1-18.285714-18.285714v-109.714286c0-9.728 8.557714-18.285714 18.285714-18.285714h109.714286c9.728 0 18.285714 8.557714 18.285714 18.285714z m0-219.428571v109.714286c0 9.728-8.557714 18.285714-18.285714 18.285714h-109.714286a18.797714 18.797714 0 0 1-18.285714-18.285714v-109.714286c0-9.728 8.557714-18.285714 18.285714-18.285714h109.714286c9.728 0 18.285714 8.557714 18.285714 18.285714z m877.714286 438.857143v109.714285c0 9.728-8.557714 18.285714-18.285714 18.285715h-768a18.797714 18.797714 0 0 1-18.285715-18.285715v-109.714285c0-9.728 8.557714-18.285714 18.285715-18.285715h768c9.728 0 18.285714 8.557714 18.285714 18.285715zM146.285714 91.428571v109.714286c0 9.728-8.557714 18.285714-18.285714 18.285714h-109.714286a18.797714 18.797714 0 0 1-18.285714-18.285714v-109.714286c0-9.728 8.557714-18.285714 18.285714-18.285714h109.714286c9.728 0 18.285714 8.557714 18.285714 18.285714z m877.714286 438.857143v109.714286c0 9.728-8.557714 18.285714-18.285714 18.285714h-768a18.797714 18.797714 0 0 1-18.285715-18.285714v-109.714286c0-9.728 8.557714-18.285714 18.285715-18.285714h768c9.728 0 18.285714 8.557714 18.285714 18.285714z m0-219.428571v109.714286c0 9.728-8.557714 18.285714-18.285714 18.285714h-768a18.797714 18.797714 0 0 1-18.285715-18.285714v-109.714286c0-9.728 8.557714-18.285714 18.285715-18.285714h768c9.728 0 18.285714 8.557714 18.285714 18.285714z m0-219.428572v109.714286c0 9.728-8.557714 18.285714-18.285714 18.285714h-768a18.797714 18.797714 0 0 1-18.285715-18.285714v-109.714286c0-9.728 8.557714-18.285714 18.285715-18.285714h768c9.728 0 18.285714 8.557714 18.285714 18.285714z"></path>
</svg>
</el-icon>
</el-radio-button>
</el-radio-group>
</div>
</div>
<div class="display-type-list" v-if="display == 'list'">
<el-table :data="fileData" style="width: 100%">
<el-table-column type="selection"/>
<el-table-column label="名称">
<!-- 自定义单元格内容 -->
<template #default="file">
<div class="list-file-info">
<FileIcon class="list-file-icon" :file="file.row"
:ext="file.row.type"/>
<span class="list-file-name">{{ 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 label="创建时间" width="200">
<template #default="file">
<span class="list-file-time">{{ formatDate(file.row.createTime) }}</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="display-type-block" v-else>
<el-row :gutter="20">
<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,$event)"
@contextmenu.prevent.stop="$refs.fileMenu.showMenu($event,file)">
<div class="file-image">
<FileIcon :file="file" style="width:90%"/>
</div>
<div class="file-name">{{ file.name }}</div>
<div class="file-info">
{{
file.type == 'folder' ? formatDate(file.createTime) : formatSize(file.size)
}}
</div>
</div>
</el-col>
</el-row>
</div>
</el-main>
</el-container>
</el-container>
</el-container>
<!-- <context-menu class="file-cxt-menu" element-id="myMenu1" ref="fileMenu" :options="fileMenuOption"-->
<!-- @option-clicked="fileMenuClick"/>-->
<!-- 新建目录 -->
<el-dialog v-model="createFolder.visible" title="新建文件夹" width="500px">
<div>
<el-input placeholder="请输入文件夹名称" v-model="createFolder.value"/>
<div style="color: red;height: 30px;line-height: 30px;">{{ createFolder.message }}</div>
</div>
<template #footer>
<!-- 将此模板的内容指定插入到footer的位置-->
<div class="dialog-footer">
<el-button @click="createFolder.visible = false">取消</el-button>
<el-button type="primary" :loading="createFolder.loading" @click="handleCreateFolder">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<style lang="less">
* {
margin: 0;
padding: 0;
}
.logo-block {
line-height: 60px;
@ -165,14 +378,6 @@ export default {
background-color: #dedede;
}
.pan-header-user-right {
float: right;
list-style: none;
}
.pan-header-user-right li {
float: left;
}
//
.file-block-item {
@ -186,6 +391,16 @@ export default {
background-color: var(--el-color-primary-light-8);
}
.file-image {
height: 130px;
display: flex;
align-items: center;
> span {
margin: auto;
}
}
.file-name {
font-size: 16px;
}

View File

@ -0,0 +1 @@
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2063" width="1000" height="1000"><path d="M128 469.333333h85.333333v85.333334H128zM128 298.666667h85.333333v85.333333H128zM128 640h85.333333v85.333333H128zM128 128h85.333333v85.333333H128zM128 810.666667h85.333333v85.333333H128z" fill="#2196F3" p-id="2064"></path><path d="M298.666667 469.333333h597.333333v85.333334H298.666667zM298.666667 298.666667h597.333333v85.333333H298.666667zM298.666667 640h597.333333v85.333333H298.666667zM298.666667 128h597.333333v85.333333H298.666667zM298.666667 810.666667h597.333333v85.333333H298.666667z" fill="#2196F3" p-id="2065"></path></svg>

After

Width:  |  Height:  |  Size: 673 B

93
web/src/assets/main.less Normal file
View File

@ -0,0 +1,93 @@
* {
margin: 0;
padding: 0;
}
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar
{
width: 4px;
height: 10px;
background-color: #F5F5F5;
}
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track
{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
border-radius: 2px;
background-color: #F5F5F5;
}
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb
{
border-radius: 2px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
background-color: #ccc;
}
.d-flex{
display: flex;
}
.logo-icon{
width: 32px;
height: 32px;
fill: #fff;
vertical-align: middle;
transform: translate(0px, -2px);
margin-right: 10px;
}
.pan-header-user-right {
float: right;
list-style: none;
li {
float: left;
line-height: 60px;
padding: 0 10px;
cursor: pointer;
}
.el-dropdown-link{
height: 30px;
line-height: 30px;
display: inline-block;
margin-top: 15px;
}
.avatar{
vertical-align: middle;
margin-right: 5px;
}
}
.list-file-icon{
width: 20px;
img{
vertical-align: middle;
}
}
.list-file-name{
margin-left: 5px;
position: relative;
top: 1px;
display: inline-block;
}
.file-cxt-menu{
font-size: 12px;
.vue-simple-context-menu{
min-width: 130px;
background-color: #fff;
}
.vue-simple-context-menu__item{
color:#333;
&:hover{
background-color: var(--el-fill-color);
color:#333;
}
}
.vue-simple-context-menu__divider{
height: 1px;
background-color: var(--el-border-color-lighter);
padding: 2px 0;
}
}

View File

@ -1,6 +1,10 @@
<template>
<span style="display:inline-block">
<img class="file-icon" :src="currentSrc" />
<el-image v-if="type == 'picture'"
:src="currentSrc" :previewSrcList="[currentSrc]"
:initial-index="4" fit="cover" :hide-on-click-modal="true"
/>
<img v-else class="file-icon" :src="currentSrc"/>
<!-- <img class="file-icon" :src="file.row.path" v-if="file.row.type == 'png'" /> -->
</span>
</template>
@ -9,32 +13,46 @@
import FolderIcon from '../assets/icons/folder.svg'
import UnknownIcon from '../assets/icons/icon.svg'
import ExeIcon from '../assets/icons/exe.svg'
import {ElMessage} from "element-plus";
export default {
//
props: {
file: {
type: Object,
required: true
},
ext: {
type: String
}
},
data() {
return {
currentSrc: FolderIcon
currentSrc: FolderIcon,
type: 'icon'
}
},
mounted(){
const type = this.file.type?.toLowerCase(); //
if(['png','jpg','jpeg','gif','webp'].includes(type)){
mounted() {
const type = this.file.type.toLowerCase(); //
if (['png', 'jpg', 'jpeg', 'gif', 'webp'].includes(type)) {
this.currentSrc = this.file.path || UnknownIcon; //
}else if(type == 'exe') {
this.type = 'picture';
} else if (type == 'exe') {
this.currentSrc = ExeIcon; //
}
},
methods: {
showPreview(file) {
//
ElMessage('暂不支持此文件的预览');
console.log(file)
}
}
}
</script>
<style scoped>
.file-icon{
.file-icon {
width: 100%;
}
</style>

View File

@ -1,11 +1,16 @@
import { createApp } from "vue";
import {createApp} from "vue";
// 导入element-plus的依赖
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import './assets/main.less'
import ContextMenu from 'vue-simple-context-menu'
import 'vue-simple-context-menu/dist/vue-simple-context-menu.css';
// 导入入口组件
import App from "./Main.vue";
createApp(App)
.use(ElementPlus)
const app = createApp(App)
app.component('ContextMenu', ContextMenu);
app.use(ElementPlus)
.mount("#app");

View File

@ -1,4 +1,3 @@
const API_PATH = "http://localhost:8080"
/**
@ -64,6 +63,9 @@ export default {
*/
list(folderPath = '/') {
return request(`/api/folder/list`, 'GET', {folderPath})
},
create(parent, name) {
return request(`/api/folder/create`, 'POST', {parent, name});
}
}
}

View File

@ -1 +1,10 @@
declare type ApiResult = { code: number, message: string, data: any }
declare type ApiResult = { code: number, message: string, data: any }
declare type FileItem = {
createTime: string,
id: number,
name: string,
path: string,
size: number,
type: 'folder' | string,
updateTime: string
}