增加阿里云、Seaweedfs上传接口
This commit is contained in:
14
README.md
14
README.md
@@ -18,6 +18,8 @@ xyFS不仅仅是独立可用的文件系统,还通过接口灵活集成以下
|
|||||||
- 7.公有云存储:阿里OSS云存储
|
- 7.公有云存储:阿里OSS云存储
|
||||||
- 8.公有云存储:七牛云
|
- 8.公有云存储:七牛云
|
||||||
- 9.公有云存储:腾讯文件云存储 CFS
|
- 9.公有云存储:腾讯文件云存储 CFS
|
||||||
|
<br>在第三方私有云领域,我推荐SeaweedFS、GridFS。在公有云领域,推荐阿里OSS和七牛云。
|
||||||
|
<br>SeaweedFS是一个高性能、自带Rest API的分布式文件系统,可访问我的博客了解:https://www.cnblogs.com/starcrm/p/9377851.html
|
||||||
|
|
||||||
#### 项目详细文档
|
#### 项目详细文档
|
||||||
|
|
||||||
@@ -66,9 +68,21 @@ API管理:
|
|||||||
<br>
|
<br>
|
||||||
<img alt="XyTalk FS" src="http://111.230.157.216/img/qiniufile.png" WIDTH="800"/>
|
<img alt="XyTalk FS" src="http://111.230.157.216/img/qiniufile.png" WIDTH="800"/>
|
||||||
<br>
|
<br>
|
||||||
|
上传到阿里云效果:
|
||||||
|
<br>
|
||||||
|
<img alt="XyTalk FS" src="http://111.230.157.216/img/alifile.png" WIDTH="800"/>
|
||||||
|
<br>
|
||||||
上传到Mongo GridFS效果:
|
上传到Mongo GridFS效果:
|
||||||
<br>
|
<br>
|
||||||
<img alt="XyTalk FS" src="http://111.230.157.216/img/gridfsfile.png" WIDTH="800" />
|
<img alt="XyTalk FS" src="http://111.230.157.216/img/gridfsfile.png" WIDTH="800" />
|
||||||
|
<br>
|
||||||
|
上传到SeaweedFS效果:
|
||||||
|
<br>
|
||||||
|
<img alt="XyTalk FS" src="http://111.230.157.216/img/seaweedf1.png" WIDTH="800" />
|
||||||
|
<br>
|
||||||
|
程序调试输出:
|
||||||
|
<br>
|
||||||
|
<img alt="XyTalk FS" src="http://111.230.157.216/img/fsdebug.png" WIDTH="800" />
|
||||||
|
|
||||||
#### 安装、使用教程
|
#### 安装、使用教程
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ storage.location = uploadfiledir
|
|||||||
# \u662f\u5426\u91cd\u65b0\u547d\u540d\u6587\u4ef6\u540d\uff0c\u5982\u679c\u662f\u4e2a\u4eba\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1ausername_ + \u539f\u6587\u4ef6\u540d\uff1b\u5982\u679c\u662f\u7fa4\u7ec4\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1agroupid_ + \u539f\u6587\u4ef6\u540d #
|
# \u662f\u5426\u91cd\u65b0\u547d\u540d\u6587\u4ef6\u540d\uff0c\u5982\u679c\u662f\u4e2a\u4eba\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1ausername_ + \u539f\u6587\u4ef6\u540d\uff1b\u5982\u679c\u662f\u7fa4\u7ec4\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1agroupid_ + \u539f\u6587\u4ef6\u540d #
|
||||||
storage.rename = true
|
storage.rename = true
|
||||||
|
|
||||||
# \u5b58\u50a8\u6e90.\u53ef\u591a\u9009.\u53ef\u4ee5\u540c\u65f6\u50a8\u5b58\u591a\u4e2a\u6570\u636e\u6e90,\u4fbf\u4e8e\u5907\u4efd #
|
# \u5b58\u50a8\u6e90.\u53ef\u591a\u9009.\u53ef\u4ee5\u540c\u65f6\u50a8\u5b58\u591a\u4e2a\u6570\u636e\u6e90,\u4fbf\u4e8e\u5907\u4efd , \u5efa\u8bae\u7b2c\u4e09\u65b9\u5b58\u50a8\u6e90\u53ea\u9009\u53d61-2\u4e2a\u5373\u53ef #
|
||||||
# \u7c7b\u578b\u6709\uff1axyfs\\FastDFS\\SeaweedFS\\MongoDB\\aliOSS\\qiniu\\CFS #
|
# \u7c7b\u578b\u6709\uff1axyfs\\FastDFS\\SeaweedFS\\MongoDB\\aliOSS\\qiniu\\CFS #
|
||||||
storage.todisk = true
|
storage.todisk = true
|
||||||
storage.toqiniu = true
|
storage.toqiniu = true
|
||||||
storage.tofastdfs = false
|
storage.tofastdfs = false
|
||||||
storage.tomongodb = true
|
storage.tomongodb = true
|
||||||
storage.toseaweedfs = false
|
storage.toseaweedfs = true
|
||||||
storage.toalioss = false
|
storage.toalioss = false
|
||||||
storage.tocfs = false
|
storage.tocfs = false
|
||||||
|
|
||||||
@@ -58,11 +58,11 @@ storage.seaweedfsport = 9333
|
|||||||
storage.seaweedfstimeout = 10
|
storage.seaweedfstimeout = 10
|
||||||
|
|
||||||
# ali OSS \u914d\u7f6e #
|
# ali OSS \u914d\u7f6e #
|
||||||
storage.aliendpoint = ""
|
storage.aliendpoint = oss-cn-shenzhen.aliyuncs.com
|
||||||
storage.aliaccesskeyid = ""
|
storage.aliaccesskeyid = LTAITVVqBncEC\u5565
|
||||||
storage.aliaccesskeysecret = ""
|
storage.aliaccesskeysecret = 9WVDXSfnPU3cFuckuPphXC4GX\u5565\u5565
|
||||||
storage.alibucketname = ""
|
storage.alibucketname = xytalk
|
||||||
storage.alidownloadkey = ""
|
storage.alidownloadkey = xytalk
|
||||||
|
|
||||||
# \u7b2c\u4e00\u6b21\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u81ea\u52a8\u521b\u5efa\u6570\u636e\u5e93\u8868\uff0c\u5982\u679c\u662f\u8fd0\u884cSQL\u811a\u672c\u5219\u65e0\u9700\u4f7f\u7528\u6b64\u914d\u7f6e #
|
# \u7b2c\u4e00\u6b21\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u81ea\u52a8\u521b\u5efa\u6570\u636e\u5e93\u8868\uff0c\u5982\u679c\u662f\u8fd0\u884cSQL\u811a\u672c\u5219\u65e0\u9700\u4f7f\u7528\u6b64\u914d\u7f6e #
|
||||||
# spring.jpa.hibernate.ddl-auto = create
|
# spring.jpa.hibernate.ddl-auto = create
|
||||||
|
|||||||
@@ -54,10 +54,12 @@ dependencies {
|
|||||||
compile group: 'org.lokra.seaweedfs', name: 'seaweedfs-client', version: '0.7.3.RELEASE'
|
compile group: 'org.lokra.seaweedfs', name: 'seaweedfs-client', version: '0.7.3.RELEASE'
|
||||||
compile group: 'com.github.tobato', name: 'fastdfs-client', version: '1.26.2'
|
compile group: 'com.github.tobato', name: 'fastdfs-client', version: '1.26.2'
|
||||||
compile group: 'com.aliyun.oss', name: 'aliyun-sdk-oss', version: '3.1.0'
|
compile group: 'com.aliyun.oss', name: 'aliyun-sdk-oss', version: '3.1.0'
|
||||||
compile group: 'org.jdom', name: 'jdom', version: '2.0.2'
|
compile group: 'org.jdom', name: 'jdom', version: '1.1.3'
|
||||||
compile group: 'com.aliyun', name: 'aliyun-java-sdk-ram', version: '3.0.0'
|
compile group: 'com.aliyun', name: 'aliyun-java-sdk-ram', version: '3.0.0'
|
||||||
compile group: 'com.aliyun', name: 'aliyun-java-sdk-sts', version: '3.0.0'
|
compile group: 'com.aliyun', name: 'aliyun-java-sdk-sts', version: '3.0.0'
|
||||||
compile group: 'com.aliyun', name: 'aliyun-java-sdk-ecs', version: '4.9.2'
|
compile group: 'com.aliyun', name: 'aliyun-java-sdk-ecs', version: '4.9.2'
|
||||||
|
compile group: 'com.sun.jersey', name: 'jersey-json', version: '1.19.4'
|
||||||
|
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'
|
||||||
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
|
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
|
||||||
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
|
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
|
||||||
|
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ public class FileUploadDownloadController {
|
|||||||
UploadFileExt ufe;
|
UploadFileExt ufe;
|
||||||
try {
|
try {
|
||||||
ufe = new UploadFileExt(finalFilename, file.getBytes(), file.getContentType(), file.getSize());
|
ufe = new UploadFileExt(finalFilename, file.getBytes(), file.getContentType(), file.getSize());
|
||||||
|
ufe.setUrl("D:/0NewIMRespo/xyFS/uploadfiledir/" + finalFilename);
|
||||||
if (ufe != null) {
|
if (ufe != null) {
|
||||||
for (FileListener fl : StoreSource.getListensers()) {
|
for (FileListener fl : StoreSource.getListensers()) {
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public class UploadFileExt {
|
|||||||
private String mimeType;
|
private String mimeType;
|
||||||
private String catalog;
|
private String catalog;
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
private byte[] bytes;
|
private byte[] bytes;
|
||||||
private File file;
|
private File file;
|
||||||
private InputStream inputStream;
|
private InputStream inputStream;
|
||||||
@@ -76,6 +77,11 @@ public class UploadFileExt {
|
|||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
return bytes;
|
return bytes;
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
package xy.FileSystem.Service;
|
package xy.FileSystem.Service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.aliyun.oss.ClientException;
|
import com.aliyun.oss.ClientException;
|
||||||
import com.aliyun.oss.OSS;
|
import com.aliyun.oss.OSS;
|
||||||
|
import com.aliyun.oss.OSSClient;
|
||||||
import com.aliyun.oss.OSSClientBuilder;
|
import com.aliyun.oss.OSSClientBuilder;
|
||||||
import com.aliyun.oss.OSSException;
|
import com.aliyun.oss.OSSException;
|
||||||
import com.aliyun.oss.model.CompleteMultipartUploadResult;
|
import com.aliyun.oss.model.CompleteMultipartUploadResult;
|
||||||
import com.aliyun.oss.model.DownloadFileRequest;
|
import com.aliyun.oss.model.DownloadFileRequest;
|
||||||
import com.aliyun.oss.model.DownloadFileResult;
|
import com.aliyun.oss.model.DownloadFileResult;
|
||||||
import com.aliyun.oss.model.ObjectMetadata;
|
import com.aliyun.oss.model.ObjectMetadata;
|
||||||
|
import com.aliyun.oss.model.PutObjectRequest;
|
||||||
|
import com.aliyun.oss.model.PutObjectResult;
|
||||||
import com.aliyun.oss.model.UploadFileRequest;
|
import com.aliyun.oss.model.UploadFileRequest;
|
||||||
import com.aliyun.oss.model.UploadFileResult;
|
import com.aliyun.oss.model.UploadFileResult;
|
||||||
import xy.FileSystem.File.FileListener;
|
import xy.FileSystem.File.FileListener;
|
||||||
@@ -26,6 +31,7 @@ public class AliService implements FileListener{
|
|||||||
StorageProperties prop;
|
StorageProperties prop;
|
||||||
|
|
||||||
private OSS init(){
|
private OSS init(){
|
||||||
|
|
||||||
return new OSSClientBuilder().build(prop.getAliendpoint(),
|
return new OSSClientBuilder().build(prop.getAliendpoint(),
|
||||||
prop.getAliaccesskeyid(),
|
prop.getAliaccesskeyid(),
|
||||||
prop.getAliaccesskeysecret());
|
prop.getAliaccesskeysecret());
|
||||||
@@ -33,20 +39,30 @@ public class AliService implements FileListener{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadResult Store(UploadFileExt ufe) {
|
public UploadResult Store(UploadFileExt ufe) {
|
||||||
//上传回调
|
//上传回调,断点续传
|
||||||
CompleteMultipartUploadResult cmuResult = store(ufe.getUrl(),ufe.getFileName());
|
//CompleteMultipartUploadResult cmuResult = store(ufe.getUrl());
|
||||||
|
//上传回调,普通上传
|
||||||
|
|
||||||
|
PutObjectResult cmuResult = store(ufe);
|
||||||
UploadResult result = new UploadResult();
|
UploadResult result = new UploadResult();
|
||||||
|
|
||||||
|
result.fileName = ufe.getFileName();
|
||||||
|
|
||||||
if (ufe.getBytes() != null) {
|
if (ufe.getBytes() != null) {
|
||||||
//TODO byte[] upload
|
result.fsize = ufe.getSize();
|
||||||
} else {
|
|
||||||
result.fileName = ufe.getFileName();
|
|
||||||
result.fsize = ufe.getFile().length();
|
|
||||||
result.hash = Integer.toString(ufe.getFile().hashCode());
|
|
||||||
result.key = cmuResult.getKey();
|
|
||||||
result.bucket = cmuResult.getBucketName();
|
|
||||||
result.location = cmuResult.getLocation();
|
|
||||||
result.tag = cmuResult.getETag();
|
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
result.fsize = ufe.getFile().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
result.key = ufe.getFileName();
|
||||||
|
result.bucket = prop.getAlibucketname();
|
||||||
|
result.location = prop.getAlibucketname();
|
||||||
|
result.tag = cmuResult.getETag();
|
||||||
|
|
||||||
|
System.out.println("#########################");
|
||||||
|
System.out.println("Ali OSS upload success,file id:"+ result.key);
|
||||||
|
System.out.println("#########################");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,13 +71,15 @@ public class AliService implements FileListener{
|
|||||||
//下载回调
|
//下载回调
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompleteMultipartUploadResult store(String filePath, String fileName) {
|
//断点续传上传,多线程
|
||||||
|
public CompleteMultipartUploadResult store(String filePath) {
|
||||||
OSS ossClient = init();
|
OSS ossClient = init();
|
||||||
try {
|
try {
|
||||||
UploadFileRequest uploadFileRequest = new UploadFileRequest(prop.getAlibucketname(), prop.getAlidownloadkey());
|
UploadFileRequest uploadFileRequest = new UploadFileRequest(prop.getAlibucketname(), prop.getAlidownloadkey());
|
||||||
//local file
|
//local file
|
||||||
uploadFileRequest.setUploadFile(filePath);
|
uploadFileRequest.setUploadFile(filePath);
|
||||||
|
|
||||||
//5线程
|
//5线程
|
||||||
uploadFileRequest.setTaskNum(5);
|
uploadFileRequest.setTaskNum(5);
|
||||||
// 切分 1MB.
|
// 切分 1MB.
|
||||||
@@ -96,6 +114,28 @@ public class AliService implements FileListener{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//断点续传上传,单线程
|
||||||
|
public PutObjectResult store(UploadFileExt object) {
|
||||||
|
try {
|
||||||
|
PutObjectRequest request = null;
|
||||||
|
if(object.getFile() != null){
|
||||||
|
request = new PutObjectRequest(prop.getAlibucketname(), object.getFileName(), object.getFile());
|
||||||
|
}else if(object.getBytes() != null){
|
||||||
|
request = new PutObjectRequest(prop.getAlibucketname(), object.getFileName(), new ByteArrayInputStream(object.getBytes()));
|
||||||
|
}else if(object.getInputStream() != null){
|
||||||
|
request = new PutObjectRequest(prop.getAlibucketname(), object.getFileName(), object.getInputStream());
|
||||||
|
}else{
|
||||||
|
throw new IllegalArgumentException("upload object is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
PutObjectResult result = init().putObject(request);
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (OSSException e) {
|
||||||
|
throw new RuntimeException(e.getErrorMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void download(String localFile, String fileKey){
|
public void download(String localFile, String fileKey){
|
||||||
|
|
||||||
OSS ossClient = init();
|
OSS ossClient = init();
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ public class SeaweedfsService implements FileListener {
|
|||||||
result.location = "";
|
result.location = "";
|
||||||
result.tag = "";
|
result.tag = "";
|
||||||
}
|
}
|
||||||
|
System.out.println("#########################");
|
||||||
|
System.out.println("Seaweedfs upload success,fid:"+ result.key);
|
||||||
|
System.out.println("#########################");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ storage.location = uploadfiledir
|
|||||||
# \u662f\u5426\u91cd\u65b0\u547d\u540d\u6587\u4ef6\u540d\uff0c\u5982\u679c\u662f\u4e2a\u4eba\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1ausername_ + \u539f\u6587\u4ef6\u540d\uff1b\u5982\u679c\u662f\u7fa4\u7ec4\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1agroupid_ + \u539f\u6587\u4ef6\u540d #
|
# \u662f\u5426\u91cd\u65b0\u547d\u540d\u6587\u4ef6\u540d\uff0c\u5982\u679c\u662f\u4e2a\u4eba\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1ausername_ + \u539f\u6587\u4ef6\u540d\uff1b\u5982\u679c\u662f\u7fa4\u7ec4\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1agroupid_ + \u539f\u6587\u4ef6\u540d #
|
||||||
storage.rename = true
|
storage.rename = true
|
||||||
|
|
||||||
# \u5b58\u50a8\u6e90.\u53ef\u591a\u9009.\u53ef\u4ee5\u540c\u65f6\u50a8\u5b58\u591a\u4e2a\u6570\u636e\u6e90,\u4fbf\u4e8e\u5907\u4efd #
|
# \u5b58\u50a8\u6e90.\u53ef\u591a\u9009.\u53ef\u4ee5\u540c\u65f6\u50a8\u5b58\u591a\u4e2a\u6570\u636e\u6e90,\u4fbf\u4e8e\u5907\u4efd , \u5efa\u8bae\u7b2c\u4e09\u65b9\u5b58\u50a8\u6e90\u53ea\u9009\u53d61-2\u4e2a\u5373\u53ef #
|
||||||
# \u7c7b\u578b\u6709\uff1axyfs\\FastDFS\\SeaweedFS\\MongoDB\\aliOSS\\qiniu\\CFS #
|
# \u7c7b\u578b\u6709\uff1axyfs\\FastDFS\\SeaweedFS\\MongoDB\\aliOSS\\qiniu\\CFS #
|
||||||
storage.todisk = true
|
storage.todisk = true
|
||||||
storage.toqiniu = true
|
storage.toqiniu = true
|
||||||
storage.tofastdfs = false
|
storage.tofastdfs = false
|
||||||
storage.tomongodb = true
|
storage.tomongodb = true
|
||||||
storage.toseaweedfs = false
|
storage.toseaweedfs = true
|
||||||
storage.toalioss = false
|
storage.toalioss = false
|
||||||
storage.tocfs = false
|
storage.tocfs = false
|
||||||
|
|
||||||
@@ -58,11 +58,11 @@ storage.seaweedfsport = 9333
|
|||||||
storage.seaweedfstimeout = 10
|
storage.seaweedfstimeout = 10
|
||||||
|
|
||||||
# ali OSS \u914d\u7f6e #
|
# ali OSS \u914d\u7f6e #
|
||||||
storage.aliendpoint = ""
|
storage.aliendpoint = oss-cn-shenzhen.aliyuncs.com
|
||||||
storage.aliaccesskeyid = ""
|
storage.aliaccesskeyid = LTAITVVqBncEC\u5565
|
||||||
storage.aliaccesskeysecret = ""
|
storage.aliaccesskeysecret = 9WVDXSfnPU3cFuckuPphXC4GX\u5565\u5565
|
||||||
storage.alibucketname = ""
|
storage.alibucketname = xytalk
|
||||||
storage.alidownloadkey = ""
|
storage.alidownloadkey = xytalk
|
||||||
|
|
||||||
# \u7b2c\u4e00\u6b21\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u81ea\u52a8\u521b\u5efa\u6570\u636e\u5e93\u8868\uff0c\u5982\u679c\u662f\u8fd0\u884cSQL\u811a\u672c\u5219\u65e0\u9700\u4f7f\u7528\u6b64\u914d\u7f6e #
|
# \u7b2c\u4e00\u6b21\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u81ea\u52a8\u521b\u5efa\u6570\u636e\u5e93\u8868\uff0c\u5982\u679c\u662f\u8fd0\u884cSQL\u811a\u672c\u5219\u65e0\u9700\u4f7f\u7528\u6b64\u914d\u7f6e #
|
||||||
# spring.jpa.hibernate.ddl-auto = create
|
# spring.jpa.hibernate.ddl-auto = create
|
||||||
|
|||||||
@@ -25,24 +25,27 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="/files/empty/" class="nav-link"><i class="fe fe-calendar"></i>日志 </a>
|
<a href="/files/empty/" class="nav-link"><i class="fe fe-calendar"></i>日志 </a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item">
|
||||||
<a href="/files/empty/" class="nav-link" data-toggle="dropdown"><i class="fe fe-settings"></i> 系统设置</a>
|
<a href="/files/empty/" class="nav-link"><i class="fe fe-calendar"></i>设置 </a>
|
||||||
<div class="dropdown-menu dropdown-menu-arrow">
|
|
||||||
<a href="./profile.html" class="dropdown-item ">Profile</a>
|
|
||||||
<a href="./login.html" class="dropdown-item ">Login</a>
|
|
||||||
<a href="./register.html" class="dropdown-item ">Register</a>
|
|
||||||
<a href="./forgot-password.html" class="dropdown-item ">Forgot password</a>
|
|
||||||
<a href="./400.html" class="dropdown-item ">400 error</a>
|
|
||||||
<a href="./401.html" class="dropdown-item ">401 error</a>
|
|
||||||
<a href="./403.html" class="dropdown-item ">403 error</a>
|
|
||||||
<a href="./404.html" class="dropdown-item ">404 error</a>
|
|
||||||
<a href="./500.html" class="dropdown-item ">500 error</a>
|
|
||||||
<a href="./503.html" class="dropdown-item ">503 error</a>
|
|
||||||
<a href="./email.html" class="dropdown-item ">Email</a>
|
|
||||||
<a href="./empty.html" class="dropdown-item ">Empty page</a>
|
|
||||||
<a href="./rtl.html" class="dropdown-item ">RTL mode</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
|
<!-- <li class="nav-item dropdown"> -->
|
||||||
|
<!-- <a href="/files/empty/" class="nav-link" data-toggle="dropdown"><i class="fe fe-settings"></i> 系统设置</a> -->
|
||||||
|
<!-- <div class="dropdown-menu dropdown-menu-arrow"> -->
|
||||||
|
<!-- <a href="./profile.html" class="dropdown-item ">Profile</a> -->
|
||||||
|
<!-- <a href="./login.html" class="dropdown-item ">Login</a> -->
|
||||||
|
<!-- <a href="./register.html" class="dropdown-item ">Register</a> -->
|
||||||
|
<!-- <a href="./forgot-password.html" class="dropdown-item ">Forgot password</a> -->
|
||||||
|
<!-- <a href="./400.html" class="dropdown-item ">400 error</a> -->
|
||||||
|
<!-- <a href="./401.html" class="dropdown-item ">401 error</a> -->
|
||||||
|
<!-- <a href="./403.html" class="dropdown-item ">403 error</a> -->
|
||||||
|
<!-- <a href="./404.html" class="dropdown-item ">404 error</a> -->
|
||||||
|
<!-- <a href="./500.html" class="dropdown-item ">500 error</a> -->
|
||||||
|
<!-- <a href="./503.html" class="dropdown-item ">503 error</a> -->
|
||||||
|
<!-- <a href="./email.html" class="dropdown-item ">Email</a> -->
|
||||||
|
<!-- <a href="./empty.html" class="dropdown-item ">Empty page</a> -->
|
||||||
|
<!-- <a href="./rtl.html" class="dropdown-item ">RTL mode</a> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
<!-- </li> -->
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user