From 1631a0faa165f7fc80f88bb244df855d9c310931 Mon Sep 17 00:00:00 2001 From: q Date: Thu, 10 Jul 2025 18:58:12 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=A7=A3=E6=9E=90=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BC=98=E5=8C=96=20v0.1.9b5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/nfd-install.sh | 86 ++++ .../main/java/cn/qaiu/parser/impl/YeTool.java | 81 ++-- web-front/babel.config.js | 3 + web-front/package.json | 15 +- web-front/public/index.html | 2 + web-front/src/App.vue | 434 +----------------- web-front/src/components/DarkMode.vue | 30 +- web-front/src/main.js | 16 +- web-front/src/styles/index.css | 164 +++++++ web-front/vue.config.js | 18 +- 10 files changed, 387 insertions(+), 462 deletions(-) create mode 100644 bin/nfd-install.sh diff --git a/bin/nfd-install.sh b/bin/nfd-install.sh new file mode 100644 index 0000000..891b2dc --- /dev/null +++ b/bin/nfd-install.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -e + +# ----------- 配置区域 ------------ +# JRE 下载目录 +JRE_DIR="/opt/custom-jre17" +# 使用阿里云镜像下载 JRE(OpenJDK 17) +JRE_TARBALL_URL="https://mirrors.tuna.tsinghua.edu.cn/Adoptium/17/jre/x64/linux/OpenJDK17U-jre_x64_linux_hotspot_17.0.15_6.tar.gz" + +# ZIP 文件下载相关 +ZIP_URL="http://www.722shop.top:6401/parser?url=https://wwsd.lanzouw.com/i65zN30nd4dc" +ZIP_DEST_DIR="/opt/target-zip" +ZIP_FILE_NAME="nfd.zip" +# -------------------------------- + +# 创建目录 +mkdir -p "$JRE_DIR" +mkdir -p "$ZIP_DEST_DIR" + +# -------- 检查 unzip 是否存在 -------- +if ! command -v unzip >/dev/null 2>&1; then + echo "unzip 未安装,正在安装..." + + if command -v apt-get >/dev/null 2>&1; then + apt-get update && apt-get install -y unzip + elif command -v yum >/dev/null 2>&1; then + yum install -y unzip + elif command -v dnf >/dev/null 2>&1; then + dnf install -y unzip + else + echo "不支持的包管理器,无法自动安装 unzip,请手动安装后重试。" + exit 1 + fi +else + echo "unzip 已安装" +fi + +# -------- 下载并解压 JRE -------- +echo "下载 JRE 17 到 $JRE_DIR..." +curl -L "$JRE_TARBALL_URL" -o "$JRE_DIR/jre17.tar.gz" + +echo "解压 JRE..." +tar -xzf "$JRE_DIR/jre17.tar.gz" -C "$JRE_DIR" --strip-components=1 +rm "$JRE_DIR/jre17.tar.gz" +echo "JRE 解压完成" + +# -------- 下载 ZIP 文件 -------- +ZIP_PATH="$ZIP_DEST_DIR/$ZIP_FILE_NAME" +echo "下载 ZIP 文件到 $ZIP_PATH..." +curl -L "$ZIP_URL" -o "$ZIP_PATH" + +# -------- 解压 ZIP 文件 -------- +echo "解压 ZIP 文件到 $ZIP_DEST_DIR..." +unzip -o "$ZIP_PATH" -d "$ZIP_DEST_DIR" +echo "解压完成" + +# -------- 启动 JAR 程序 -------- +echo "进入 JAR 目录并后台运行程序..." + +JAR_DIR="/opt/target-zip/netdisk-fast-download" +JAR_FILE="netdisk-fast-download.jar" +JAVA_BIN="$JRE_DIR/bin/java" +LOG_FILE="$JAR_DIR/app.log" + +if [ ! -d "$JAR_DIR" ]; then + echo "[错误] 找不到 JAR 目录: $JAR_DIR" + exit 1 +fi + +cd "$JAR_DIR" + +if [ ! -f "$JAR_FILE" ]; then + echo "[错误] 找不到 JAR 文件: $JAR_FILE" + exit 1 +fi + +if [ ! -x "$JAVA_BIN" ]; then + echo "[错误] 找不到可执行的 java: $JAVA_BIN" + exit 1 +fi + +# 后台运行,日志记录 +nohup "$JAVA_BIN" -jar "$JAR_FILE" > "$LOG_FILE" 2>&1 & + +echo "程序已在后台启动 ✅" +echo "日志路径: $LOG_FILE" \ No newline at end of file diff --git a/parser/src/main/java/cn/qaiu/parser/impl/YeTool.java b/parser/src/main/java/cn/qaiu/parser/impl/YeTool.java index 4151517..2d2bc41 100644 --- a/parser/src/main/java/cn/qaiu/parser/impl/YeTool.java +++ b/parser/src/main/java/cn/qaiu/parser/impl/YeTool.java @@ -4,6 +4,7 @@ import cn.qaiu.entity.FileInfo; import cn.qaiu.entity.ShareLinkInfo; import cn.qaiu.parser.PanBase; import cn.qaiu.util.CommonUtils; +import cn.qaiu.util.FileSizeConverter; import cn.qaiu.util.JsExecUtils; import io.vertx.core.Future; import io.vertx.core.MultiMap; @@ -271,22 +272,68 @@ public class YeTool extends PanBase { for (int i = 0; i < infoList.size(); i++) { JsonObject item = infoList.getJsonObject(i); FileInfo fileInfo = new FileInfo(); + // "FileId": 16603582, + // "FileName": "pdf", + // "Type": 1, + // "Size": 0, + // "ContentType": "0", + // "S3KeyFlag": "", + // "CreateAt": "2025-07-09T06:56:20+08:00", + // "UpdateAt": "2025-07-09T06:56:20+08:00", + // "Etag": "", + // "DownloadUrl": "", + // "Status": 0, + // "ParentFileId": 16603579, + // "Category": 0, + // "PunishFlag": 0, + // "StorageNode": "m0", + // "PreviewType": 0 + + // => + // { + // "ShareKey":"iaKtVv-FTaCd", + // "FileID":16604189, + // "S3keyFlag":"1815268665-0", + // "Size":425929, + // "Etag":"70049de67075ab2b269c62d690424601", + // "OrderId":""} + JsonObject postData = JsonObject.of() + .put("ShareKey", shareKey) + .put("FileID", item.getInteger("FileId")) + .put("S3keyFlag", item.getString("S3KeyFlag")) + .put("Size", item.getLong("Size")) + .put("Etag", item.getString("Etag")); + + byte[] encode = Base64.getEncoder().encode(postData.encode().getBytes()); + String param = new String(encode); + if (item.getInteger("Type") == 0) { // 文件 fileInfo.setFileName(item.getString("FileName")) .setFileId(item.getString("FileId")) .setFileType("file") .setSize(item.getLong("Size")) - .setParserUrl(String.format("%s/v2/getFileList/%s/%s", getDomainName(), - shareLinkInfo.getType(), generateParam(item))) + .setCreateTime(item.getString("CreateAt")) + .setUpdateTime(item.getString("UpdateAt")) + .setSizeStr(FileSizeConverter.convertToReadableSize(item.getLong("Size"))) + .setParserUrl(String.format("%s/v2/redirectUrl/%s/%s", getDomainName(), + shareLinkInfo.getType(), param)) .setPreviewUrl(String.format("%s/v2/viewUrl/%s/%s", getDomainName(), - shareLinkInfo.getType(), generateParam(item))); + shareLinkInfo.getType(), param)); result.add(fileInfo); } else if (item.getInteger("Type") == 1) { // 目录 fileInfo.setFileName(item.getString("FileName")) .setFileId(item.getString("FileId")) + .setCreateTime(item.getString("CreateAt")) + .setUpdateTime(item.getString("UpdateAt")) + .setSize(0L) .setFileType("folder") - .setParserUrl(String.format("%s/v2/getFileList?url=%s&dirId=%s", getDomainName(), - shareLinkInfo.getShareUrl(), item.getString("FileId"))); + .setParserUrl( + String.format("%s/v2/getFileList?url=%s&dirId=%s&pwd=%s", + getDomainName(), + shareLinkInfo.getShareUrl(), + item.getString("FileId"), + pwd) + ); result.add(fileInfo); } } @@ -296,33 +343,11 @@ public class YeTool extends PanBase { return promise.future(); } - @Override public Future parseById() { - Promise promise = Promise.promise(); JsonObject paramJson = (JsonObject) shareLinkInfo.getOtherParam().get("paramJson"); - // 调用下载接口获取直链 - client.getAbs(UriTemplate.of(DOWNLOAD_API_URL)) - .setTemplateParam("authK", paramJson.getString("authK")) - .setTemplateParam("authV", paramJson.getString("authV")) - .putHeaders(header) - .send().onSuccess(res -> { - JsonObject response = asJson(res); - if (response.getInteger("code") != 0) { - promise.fail("API错误: " + response.getString("message")); - return; - } - String downloadUrl = response.getJsonObject("data").getString("redirect_url"); - promise.complete(downloadUrl); - }).onFailure(promise::fail); - + down(client, paramJson, DOWNLOAD_API_URL); return promise.future(); } - - - private String generateParam(JsonObject fileJson) { - // 生成API请求所需的加密参数 - return ""; - } } diff --git a/web-front/babel.config.js b/web-front/babel.config.js index e955840..5dc91c5 100644 --- a/web-front/babel.config.js +++ b/web-front/babel.config.js @@ -1,5 +1,8 @@ module.exports = { presets: [ '@vue/cli-plugin-babel/preset' + ], + plugins: [ + '@vue/babel-plugin-transform-vue-jsx' ] } diff --git a/web-front/package.json b/web-front/package.json index d416dcf..0bead4e 100644 --- a/web-front/package.json +++ b/web-front/package.json @@ -16,18 +16,22 @@ "core-js": "^3.8.3", "element-plus": "^2.8.7", "qrcode": "^1.5.4", + "splitpanes": "^4.0.4", "vue": "^3.5.12", "vue-clipboard3": "^2.0.0", + "vue-router": "^4.5.1", "vue3-json-viewer": "2.2.2" }, "devDependencies": { "@babel/core": "^7.26.0", "@babel/eslint-parser": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.26.0", + "@vue/babel-plugin-transform-vue-jsx": "^1.4.0", "@vue/cli-plugin-babel": "~5.0.8", "@vue/cli-plugin-eslint": "~5.0.8", "@vue/cli-service": "~5.0.8", "compression-webpack-plugin": "^11.1.0", - "eslint": "^9.14.0", + "eslint": "^9.0.0", "eslint-plugin-vue": "^9.30.0", "filemanager-webpack-plugin": "8.0.0" }, @@ -49,5 +53,12 @@ "> 1%", "last 2 versions", "not dead" - ] + ], + "engines": { + "node": ">=16.0.0 <=22.0.0", + "npm": ">=8.0.0" + }, + "overrides": { + "eslint": "^9.0.0" + } } diff --git a/web-front/public/index.html b/web-front/public/index.html index 57a2339..db7187f 100644 --- a/web-front/public/index.html +++ b/web-front/public/index.html @@ -9,6 +9,8 @@ content="Netdisk fast download,网盘直链解析工具"> + + diff --git a/web-front/src/components/DarkMode.vue b/web-front/src/components/DarkMode.vue index 5318652..6e420f3 100644 --- a/web-front/src/components/DarkMode.vue +++ b/web-front/src/components/DarkMode.vue @@ -11,14 +11,18 @@ diff --git a/web-front/src/main.js b/web-front/src/main.js index a448ee2..0c1ea4d 100644 --- a/web-front/src/main.js +++ b/web-front/src/main.js @@ -9,22 +9,24 @@ import 'element-plus/dist/index.css' import 'element-plus/theme-chalk/dark/css-vars.css' import "vue3-json-viewer/dist/index.css"; import './styles/dark/css-vars.css' +import router from './router' -window.$vueApp = Vue.createApp(App) +const app = Vue.createApp(App) +app.use(router) import * as ElementPlusIconsVue from '@element-plus/icons-vue' for (const [key, component] of Object.entries(ElementPlusIconsVue)) { - window.$vueApp.component(key, component) + app.component(key, component) } // Import JsonViewer as a Vue.js plugin -window.$vueApp.use(JsonViewer) -window.$vueApp.use(DirectiveExtensions) +app.use(JsonViewer) +app.use(DirectiveExtensions) // or // components: {JsonViewer} -window.$vueApp.use(VueClipboard) -window.$vueApp.use(ElementPlus) -window.$vueApp.mount('#app') +app.use(VueClipboard) +app.use(ElementPlus) +app.mount('#app') diff --git a/web-front/src/styles/index.css b/web-front/src/styles/index.css index e69de29..add06bd 100644 --- a/web-front/src/styles/index.css +++ b/web-front/src/styles/index.css @@ -0,0 +1,164 @@ +/* 全局样式 */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Avenir', Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + transition: all 0.3s ease; +} + +/* 亮色主题 */ +body { + background-color: #f5f7fa; + color: #2c3e50; +} + +/* 暗色主题 */ +body.dark-theme { + background-color: #1a1a1a; + color: #ffffff; +} + +/* Element Plus 暗色主题适配 */ +.dark-theme .el-card { + background-color: #2d2d2d !important; + border-color: #404040 !important; + color: #ffffff !important; +} + +.dark-theme .el-input__inner { + background-color: #404040 !important; + border-color: #555555 !important; + color: #ffffff !important; +} + +.dark-theme .el-input__inner::placeholder { + color: #bdc3c7 !important; +} + +.dark-theme .el-button { + background-color: #404040 !important; + border-color: #555555 !important; + color: #ffffff !important; +} + +.dark-theme .el-button:hover { + background-color: #555555 !important; +} + +.dark-theme .el-button--primary { + background-color: #409eff !important; + border-color: #409eff !important; +} + +.dark-theme .el-button--primary:hover { + background-color: #66b1ff !important; +} + +.dark-theme .el-button--success { + background-color: #67c23a !important; + border-color: #67c23a !important; +} + +.dark-theme .el-button--success:hover { + background-color: #85ce61 !important; +} + +.dark-theme .el-switch__core { + background-color: #555555 !important; +} + +.dark-theme .el-descriptions { + background-color: #2d2d2d !important; + color: #ffffff !important; +} + +.dark-theme .el-descriptions__label { + color: #bdc3c7 !important; +} + +.dark-theme .el-descriptions__content { + color: #ffffff !important; +} + +.dark-theme .el-dialog { + background-color: #2d2d2d !important; + color: #ffffff !important; +} + +.dark-theme .el-dialog__title { + color: #ffffff !important; +} + +.dark-theme .el-dialog__body { + color: #ffffff !important; +} + +.dark-theme .el-message { + background-color: #2d2d2d !important; + color: #ffffff !important; +} + +.dark-theme .el-message--success { + background-color: #67c23a !important; + color: #ffffff !important; +} + +.dark-theme .el-message--error { + background-color: #f56c6c !important; + color: #ffffff !important; +} + +.dark-theme .el-message--warning { + background-color: #e6a23c !important; + color: #ffffff !important; +} + +.dark-theme .el-message--info { + background-color: #909399 !important; + color: #ffffff !important; +} + +/* 链接颜色 */ +.dark-theme a { + color: #4a9eff !important; +} + +.dark-theme a:hover { + color: #66b1ff !important; +} + +/* 滚动条样式 */ +.dark-theme ::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +.dark-theme ::-webkit-scrollbar-track { + background: #2d2d2d; +} + +.dark-theme ::-webkit-scrollbar-thumb { + background: #555555; + border-radius: 4px; +} + +.dark-theme ::-webkit-scrollbar-thumb:hover { + background: #666666; +} + +/* 选择文本样式 */ +.dark-theme ::selection { + background-color: #409eff; + color: #ffffff; +} + +.dark-theme ::-moz-selection { + background-color: #409eff; + color: #ffffff; +} diff --git a/web-front/vue.config.js b/web-front/vue.config.js index af3a442..8dd7b4c 100644 --- a/web-front/vue.config.js +++ b/web-front/vue.config.js @@ -16,15 +16,27 @@ module.exports = { host: '127.0.0.1', port: 6444, proxy: { - '/': { - target: 'http://127.0.0.1:6400', // 请求本地 + '/parser': { + target: 'http://127.0.0.1:6400/', // 请求本地 + ws: false + }, + '/v2': { + target: 'http://127.0.0.1:6400/', // 请求本地 + ws: false + }, + '/json': { + target: 'http://127.0.0.1:6400/', // 请求本地 + ws: false + }, + '/d': { + target: 'http://127.0.0.1:6400/', // 请求本地 ws: false }, } }, configureWebpack: { // provide the app's title in webpack's name field, so that - // it can be accessed in index.html to inject the correct title. + // it can be accessed in list.html to inject the correct title. name: 'Netdisk fast download', resolve: { alias: {