diff --git a/README.md b/README.md index f7136473b8db7a6cb62ed19a92d0421182a4e47d..102fa541c4ed3826d6f34d875341dc52e17716e8 100644 --- a/README.md +++ b/README.md @@ -9,21 +9,19 @@ ### 简介 咸鱼云网盘目前是一个用于共享文件和实现私人网盘基本功能的系统,目前仍处于原型开发阶段,许多功能和文档尚未完善。 ### 特性 -- 有公共公开网盘功能,可作为资源站 -- 私人网盘功能 -- 前后端分离,可编写多个前端项目实现全平台支持 +- 同时具有公共网盘与私人网盘,公共资源站与私有存储云两不误 - 相同文件只存一份,硬盘空间利用率高 -- 可生成文件下载直链 +- 文件下载直链极速分享 +- 支持FTP访问 +- 文件索引与缓存,海量文件搜索快速响应 + ### 项目近期开发可能实现的特性 -- 公共网盘支持唯一存储(UNIQUE)模式 - 离线下载 -- FTP私人网盘的读写支持 - -### 项目计划实现的基本特性(可能会咕咕咕) - 分享私人文件/目录 - 创建文件收集 -- 离线下载 - 在线解压缩 + +### 项目计划实现的基本特性(可能会咕咕咕) - 分布式存储 - WebDav访问支持 - Samba访问支持 @@ -49,11 +47,18 @@ cd script ./start ``` +### 命令行选项 +- --switch 可选值:RAW/UNIQUE,启动存储切换程序,一般用于低版本UNIQUE模式下升级到新版本以解决兼容性问题,以bash下为例: + ```shell script + 项目目录/script@localhost $ start.sh --switch=RAW + ``` + 注意:对数据而言这是高危操作,仍然建议提前备份好数据防止丢失 + ### 协议支持 - FTP(实验性功能预览) 1. 默认开启和使用21端口,可通过参数`ftp-port`进行修改 2. Linux下非root用户请使用大于1024的端口号(不建议以root用户身份或通过sudo运该项目),但可利用端口转发实现21端口到FTP端口的转发 - 3. 暂时只支持公共网盘只读,后续开发会不断完善FTP的支持 + 3. 外部网络设备需要访问FTP时,请检查`ftp_passive_addr`参数是否为用户可访问的地址,默认是localhost,外部网络设备访问时会出现连接错误 - WebDav 暂不支持,未来版本开发 - Samba diff --git a/pom.xml b/pom.xml index 4baa14a4155bb3813d70426aab33d0463363132d..1caf011253c1d0f4495c8ce4028c4f27b4e50cb0 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.xiaotao saltedfishcloud - 1.0.0-SNAPSHOT + 1.1.7-RELEASE saltedfishcloud 咸鱼云网盘 @@ -115,6 +115,28 @@ runtime true + + + + javax.xml.bind + jaxb-api + 2.3.0 + + + com.sun.xml.bind + jaxb-impl + 2.3.0 + + + com.sun.xml.bind + jaxb-core + 2.3.0 + + + javax.activation + activation + 1.1.1 + @@ -126,6 +148,17 @@ true + + org.apache.maven.plugins + maven-resources-plugin + 2.7 + + + ^ + + false + + diff --git a/script/start.bat b/script/start.bat index 783b1a627e8b47bee2e3e77fa41870cc854ac528..45ae897e1002e0c2c3381adf5be52e5d5b28e8e3 100644 --- a/script/start.bat +++ b/script/start.bat @@ -1,22 +1,22 @@ @echo off -@REM 应用程序参数设置 +@REM Ӧó -@REM server_port 服务器端口 -@REM public_root 公共网盘存储位置 -@REM store_root 私人网盘及用户数据存储位置 -@REM store_type 初始存储方式,可选unique或raw -@REM reg_code 注册邀请码 -@REM sync_delay 同步延迟,单位分支,-1关闭 -@REM sync_launch 启动后立即同步 -@REM ftp_port FTP服务端口 +@REM server_port ˿ +@REM public_root ̴洢λ +@REM store_root ˽̼ûݴ洢λ +@REM store_type ʼ洢ʽѡuniqueraw +@REM reg_code ע +@REM sync_delay ͬӳ٣λ֧-1ر +@REM sync_launch ͬ +@REM ftp_port FTP˿ -@REM ftp_passive_port FTP被动模式数据端口 - @REM FTP服务被动模式端口范围 - @REM 2300 : 被动模式仅使用2300做数据端口 - @REM 2300-2399 : 指定闭区间端口范围 - @REM 2300- : 2300开始到往后的所有端口 - @REM 2300, 2305, 2400- : 指定2300,2305和2400开始到往后的所有端口 -@REM ftp_passive_addr FTP服务被动模式地址(在外网环境需要改为公网地址) +@REM ftp_passive_port FTPģʽݶ˿ + @REM FTP񱻶ģʽ˿ڷΧ + @REM 2300 : ģʽʹ2300ݶ˿ + @REM 2300-2399 : ָ˿ڷΧ + @REM 2300- : 2300ʼж˿ + @REM 2300, 2305, 2400- : ָ230023052400ʼж˿ +@REM ftp_passive_addr FTP񱻶ģʽַҪΪַ set server_port=8087 set public_root=data/public set store_root=data/xyy @@ -28,7 +28,7 @@ set ftp_port=21 set ftp_passive_addr=localhost set ftp_passive_port=1140-5140 -@REM 数据源设置 +@REM Դ set db_host=127.0.0.1 set db_port=3306 set db_name=xyy @@ -42,7 +42,8 @@ set redis_port=6379 set jdbc_url=jdbc:mysql://%db_host%:%db_port%/%db_name%?%db_params% -java -jar ../target/saltedfishcloud-1.0.0-SNAPSHOT.jar ^ +for /F %%i in ('cmd /r dir "../target" /b ^| findstr "saltedfishcloud-.*.jar$"') do ( set jar_name=%%i ) +java -jar ../target/%jar_name% ^ --server.port=%server_port% ^ --spring.datasource.druid.url=%jdbc_url% ^ --spring.datasource.druid.username=%db_username% ^ @@ -58,4 +59,4 @@ java -jar ../target/saltedfishcloud-1.0.0-SNAPSHOT.jar ^ --sync-launch=%sync_launch% ^ --ftp-port=%ftp_port% ^ --ftp-passive-addr=%ftp_passive_addr% ^ ---ftp-passive-port=%ftp_passive_port% +--ftp-passive-port=%ftp_passive_port% %* diff --git a/script/start.sh b/script/start.sh index d77a10b0e5ce655d9e026c4adc75c6c7d305cc0d..fca1ff941cd5d7045e8f0ccb82fb17f0be35c29c 100755 --- a/script/start.sh +++ b/script/start.sh @@ -16,16 +16,16 @@ # 2300- : 2300开始到往后的所有端口 # 2300, 2305, 2400- : 指定2300,2305和2400开始到往后的所有端口 # ftp_passive_addr FTP服务被动模式地址(在外网环境需要改为公网地址) -server_port=8087 -public_root=data/public -store_root=data/xyy -store_type=unique -reg_code=10241024 -sync_delay=5 -sync_launch=false -ftp_port=21 -ftp-passive-addr=localhost -ftp-passive-port=1140-5140 +server_port="8087" +public_root="/data/public" +store_root="/data/xyy" +store_type="unique" +reg_code="10241024" +sync_delay="5" +sync_launch="false" +ftp_port="2121" +ftp_passive_addr="localhost" +ftp_passive_port="1140-5140" # 数据源设置 db_host="127.0.0.1" @@ -41,7 +41,8 @@ redis_port="6379" jdbc_url="jdbc:mysql://${db_host}:${db_port}/${db_name}?${db_params}" -java -Dfile.encoding=utf-8 -jar ../target/saltedfishcloud-1.0.0-SNAPSHOT.jar \ +jar_name=`ls ../target/saltedfishcloud-*.jar` +java -Dfile.encoding=utf-8 -jar $jar_name \ --server.port=$server_port \ --spring.datasource.druid.url="$jdbc_url" \ --spring.datasource.druid.username="$db_username" \ @@ -57,4 +58,4 @@ java -Dfile.encoding=utf-8 -jar ../target/saltedfishcloud-1.0.0-SNAPSHOT.jar \ --sync-launch=$sync_launch \ --ftp-port=$ftp_port \ --ftp-passive-addr=$ftp_passive_addr \ ---ftp-passive-port=$ftp_passive_port +--ftp-passive-port=$ftp_passive_port $* diff --git a/src/main/java/com/xiaotao/saltedfishcloud/SaltedfishcloudApplication.java b/src/main/java/com/xiaotao/saltedfishcloud/SaltedfishcloudApplication.java index 6cada403e4fc21203f3043e1af660587632e7282..249a8fc5c417c4c1943fb4e6e1ac3425116249d4 100644 --- a/src/main/java/com/xiaotao/saltedfishcloud/SaltedfishcloudApplication.java +++ b/src/main/java/com/xiaotao/saltedfishcloud/SaltedfishcloudApplication.java @@ -1,5 +1,7 @@ package com.xiaotao.saltedfishcloud; +import com.xiaotao.saltedfishcloud.listener.StartListener; +import com.xiaotao.saltedfishcloud.utils.SpringUtils; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -16,7 +18,9 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; public class SaltedfishcloudApplication { public static void main(String[] args) { - SpringApplication.run(SaltedfishcloudApplication.class, args); + SpringApplication sa = new SpringApplication(SaltedfishcloudApplication.class); + SpringUtils.SPRING_CONTEXT = sa.run(args); + } } diff --git a/src/main/java/com/xiaotao/saltedfishcloud/config/CommandLineOption.java b/src/main/java/com/xiaotao/saltedfishcloud/config/CommandLineOption.java new file mode 100644 index 0000000000000000000000000000000000000000..58e3daa004d330d10ccc6c766cf2845a58399f58 --- /dev/null +++ b/src/main/java/com/xiaotao/saltedfishcloud/config/CommandLineOption.java @@ -0,0 +1,30 @@ +package com.xiaotao.saltedfishcloud.config; + +import org.springframework.boot.ApplicationArguments; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class CommandLineOption { + private static ApplicationArguments ARGS; + public static final String SWITCH = "switch"; + + CommandLineOption(ApplicationArguments applicationArguments) { + ARGS = applicationArguments; + } + + public static String getValue(String key) { + return getValue(key, null); + } + + public static String getValue(String key, String defaultValue) { + List val = ARGS.getOptionValues(key); + if (val == null || val.isEmpty()) { + return defaultValue; + } else { + return val.get(0); + } + } + +} diff --git a/src/main/java/com/xiaotao/saltedfishcloud/config/DiskConfig.java b/src/main/java/com/xiaotao/saltedfishcloud/config/DiskConfig.java index e69094c5a146c22f61c79e9c084872e6f6c7095f..3d9725d0f3178216449c1a502e63cef20b60c838 100644 --- a/src/main/java/com/xiaotao/saltedfishcloud/config/DiskConfig.java +++ b/src/main/java/com/xiaotao/saltedfishcloud/config/DiskConfig.java @@ -5,13 +5,14 @@ import com.xiaotao.saltedfishcloud.dao.UserDao; import com.xiaotao.saltedfishcloud.enums.ReadOnlyLevel; import com.xiaotao.saltedfishcloud.exception.HasResultException; import com.xiaotao.saltedfishcloud.po.User; +import com.xiaotao.saltedfishcloud.service.config.version.Version; import com.xiaotao.saltedfishcloud.service.file.path.PathHandler; import com.xiaotao.saltedfishcloud.service.file.path.RawPathHandler; import com.xiaotao.saltedfishcloud.service.file.path.UniquePathHandler; +import com.xiaotao.saltedfishcloud.utils.OSInfo; import com.xiaotao.saltedfishcloud.utils.SecureUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import java.io.File; @@ -23,10 +24,9 @@ import java.util.Objects; * 全局配置信息类,用于读取配置文件中的参数 */ @Component -@PropertySource("classpath:config.properties") @Slf4j public class DiskConfig { - public static final String VERSION = "1.0.0-SNAPSHOT"; + public static Version VERSION; public static RawPathHandler rawPathHandler; public static UniquePathHandler uniquePathHandler; @@ -114,6 +114,11 @@ public class DiskConfig { } } + @Value("${app.version}") + public void setVersion(String v) { + VERSION = Version.load(v); + } + @Value("${reg-code}") public void setRegCode(String v) { REG_CODE = v; @@ -132,6 +137,9 @@ public class DiskConfig { @Value("${public-root}") public void setPublicRoot(String root) { + if (!OSInfo.isWindows() && !root.startsWith("/")) { + throw new IllegalArgumentException("public-root must be start with \"/\" in Linux"); + } log.info("[公共网盘路径]" + root); File file = new File(root); DiskConfig.PUBLIC_ROOT =file.getPath(); @@ -139,6 +147,9 @@ public class DiskConfig { @Value("${store-root}") public void setStoreRoot(String root) { + if (!OSInfo.isWindows() && !root.startsWith("/")) { + throw new IllegalArgumentException("store-root must be start with \"/\" in Linux"); + } log.info("[私人网盘根目录]" + root); File file = new File(root); DiskConfig.STORE_ROOT =file.getPath(); @@ -183,11 +194,7 @@ public class DiskConfig { * @return 路径操纵器示例 */ public static PathHandler getPathHandler() { - if (STORE_TYPE == StoreType.RAW) { - return rawPathHandler; - } else { - return uniquePathHandler; - } + return rawPathHandler; } /** diff --git a/src/main/java/com/xiaotao/saltedfishcloud/config/StoreType.java b/src/main/java/com/xiaotao/saltedfishcloud/config/StoreType.java index 5e35b34f5ab2083a4eddc21998b6f46156a466aa..0b853ef420469258a4e4232318554a905e9f5aef 100644 --- a/src/main/java/com/xiaotao/saltedfishcloud/config/StoreType.java +++ b/src/main/java/com/xiaotao/saltedfishcloud/config/StoreType.java @@ -1,8 +1,8 @@ package com.xiaotao.saltedfishcloud.config; -import com.xiaotao.saltedfishcloud.enums.ConfigName; +import com.xiaotao.saltedfishcloud.service.config.ConfigName; -import static com.xiaotao.saltedfishcloud.enums.ConfigName.STORE_TYPE; +import static com.xiaotao.saltedfishcloud.service.config.ConfigName.STORE_TYPE; public enum StoreType { RAW,UNIQUE; diff --git a/src/main/java/com/xiaotao/saltedfishcloud/controller/admin/SysController.java b/src/main/java/com/xiaotao/saltedfishcloud/controller/admin/SysController.java index a4743ef9578df5ebfb988596f2c166a635916d87..313cf9670bbcefe89f5cf64fcd925dc45f21af00 100644 --- a/src/main/java/com/xiaotao/saltedfishcloud/controller/admin/SysController.java +++ b/src/main/java/com/xiaotao/saltedfishcloud/controller/admin/SysController.java @@ -4,7 +4,7 @@ import com.xiaotao.saltedfishcloud.annotations.ReadOnlyBlock; import com.xiaotao.saltedfishcloud.config.DiskConfig; import com.xiaotao.saltedfishcloud.config.StoreType; import com.xiaotao.saltedfishcloud.dao.ConfigDao; -import com.xiaotao.saltedfishcloud.enums.ConfigName; +import com.xiaotao.saltedfishcloud.service.config.ConfigName; import com.xiaotao.saltedfishcloud.po.ConfigInfo; import com.xiaotao.saltedfishcloud.po.JsonResult; import com.xiaotao.saltedfishcloud.service.config.ConfigService; diff --git a/src/main/java/com/xiaotao/saltedfishcloud/dao/ConfigDao.java b/src/main/java/com/xiaotao/saltedfishcloud/dao/ConfigDao.java index a1523d7bd318f9e5dbeb2c59c2dcf7b794a2b6eb..d9faecaa62812e4ccbb253ea4a204a88d335d82f 100644 --- a/src/main/java/com/xiaotao/saltedfishcloud/dao/ConfigDao.java +++ b/src/main/java/com/xiaotao/saltedfishcloud/dao/ConfigDao.java @@ -1,6 +1,6 @@ package com.xiaotao.saltedfishcloud.dao; -import com.xiaotao.saltedfishcloud.enums.ConfigName; +import com.xiaotao.saltedfishcloud.service.config.ConfigName; import com.xiaotao.saltedfishcloud.po.ConfigInfo; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; @@ -16,6 +16,21 @@ public interface ConfigDao { @Select("SELECT `value` FROM config WHERE `key` = #{key}") String getConfigure(ConfigName key); + /** + * 读取一条配置 + * @param key 配置键名 + * @param defaultValue 当配置项不存在时返回的默认值 + * @return 配置值 + */ + default String getConfigure(ConfigName key, String defaultValue) { + String configure = getConfigure(key); + if (configure != null) { + return configure; + } else { + return defaultValue; + } + } + /** * 读取所有配置选项 * @return @@ -30,4 +45,13 @@ public interface ConfigDao { */ @Insert("INSERT INTO config (`key`,`value`) VALUES (#{key}, #{value}) ON DUPLICATE KEY UPDATE `value`=#{value}") int setConfigure(ConfigName key, String value); + + /** + * 设置一条配置信息 + * @param key 键 + * @param value 值 + */ + default int setConfigure(ConfigName key, Enum value) { + return setConfigure(key, value.toString()); + } } diff --git a/src/main/java/com/xiaotao/saltedfishcloud/dao/FileDao.java b/src/main/java/com/xiaotao/saltedfishcloud/dao/FileDao.java index b6118a29b9cc0b0af41d8831171ae263ffe3e3ec..c299f42c39fb47b3828aa05c180914b8a64f2f3f 100644 --- a/src/main/java/com/xiaotao/saltedfishcloud/dao/FileDao.java +++ b/src/main/java/com/xiaotao/saltedfishcloud/dao/FileDao.java @@ -24,7 +24,7 @@ public interface FileDao { */ @Select({ "