pikpak批量下载助手

基于原版pikpak助手plus修改。修正了下载一次后无法再次下载的问题。

目前為 2025-08-28 提交的版本,檢視 最新版本

// ==UserScript==
// @name         pikpak批量下载助手
// @namespace    http://tampermonkey.net/
// @version      1.3.4-final
// @author       jdysya (modified by Assistant)
// @description  基于原版pikpak助手plus修改。修正了下载一次后无法再次下载的问题。
// @license      MIT
// @icon         https://www.google.com/s2/favicons?sz=64&domain=mypikpak.com
// @match        https://mypikpak.com/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// ==/UserScript==

(function(vue) {
    'use strict';

    // --- 原作者的样式代码,不做任何修改 ---
    (a => { const o = document.createElement("style"); o.dataset.source = "vite-plugin-monkey", o.innerText = a, document.head.appendChild(o) })(" .dialog[data-v-b2d19a6a]{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;z-index:10000;padding:30px;box-shadow:0 5px 15px #0000004d;border-radius:10px;width:90%;max-width:700px;box-sizing:border-box}.dialog h2[data-v-b2d19a6a]{text-align:center;color:#333;margin-bottom:20px}.dialog .close[data-v-b2d19a6a]{position:absolute;right:15px;top:15px;font-size:30px;cursor:pointer;color:#999;transition:color .3s ease}.dialog .close[data-v-b2d19a6a]:hover{color:#666}.toolbar[data-v-b2d19a6a]{display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;padding-bottom:10px;border-bottom:1px solid #eee}.toolbar input[type=checkbox][data-v-b2d19a6a]{margin-right:8px;transform:scale(1.2)}.sort-options button[data-v-b2d19a6a]{margin-left:10px;padding:8px 15px;border:1px solid #dcdfe6;background-color:#f4f4f5;color:#606266;cursor:pointer;border-radius:4px;transition:all .3s ease}.sort-options button[data-v-b2d19a6a]:hover{background-color:#e9e9eb;border-color:#d3d4d6;color:#303133}.movies[data-v-b2d19a6a]{margin-top:10px;height:400px;overflow-y:auto;border:1px solid #ebeef5;border-radius:4px;padding:10px;background-color:#fdfdfd}.movies li[data-v-b2d19a6a]{display:flex;align-items:center;padding:8px 0;border-bottom:1px dashed #f0f0f0;font-size:14px;color:#303133}.movies li .file-info[data-v-b2d19a6a]{margin-left:auto;color:#606266;font-size:12px}.movies li[data-v-b2d19a6a]:last-child{border-bottom:none}.movies li input[type=checkbox][data-v-b2d19a6a]{margin-right:10px;transform:scale(1.1)}.movies li .icon[data-v-b2d19a6a]{margin-right:8px;font-size:1.2em}.footer[data-v-b2d19a6a]{margin-top:20px;display:flex;flex-direction:row-reverse}.btn.el-button[data-v-b2d19a6a]{padding:10px 20px;background-color:#409eff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;transition:background-color .3s ease}.btn.el-button[data-v-b2d19a6a]:hover{background-color:#66b1ff}.dialog[data-v-3448452d]{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;z-index:10000;padding:30px;box-shadow:0 5px 15px #0000004d;border-radius:10px;width:90%;max-width:500px;box-sizing:border-box}.dialog h2[data-v-3448452d]{text-align:center;color:#333;margin-bottom:20px}.dialog .close[data-v-3448452d]{position:absolute;right:15px;top:15px;font-size:30px;cursor:pointer;color:#999;transition:color .3s ease}.dialog .close[data-v-3448452d]:hover{color:#666}.config-list[data-v-3448452d]{margin-top:20px}.config-list li[data-v-3448452d]{margin-bottom:15px}.config-list li .label[data-v-3448452d]{font-weight:700;margin-bottom:5px;display:block;color:#555}.config-list li input[type=text][data-v-3448452d]{width:100%;padding:10px;border:1px solid #dcdfe6;border-radius:4px;box-sizing:border-box;font-size:14px;transition:border-color .3s ease}.config-list li input[type=text][data-v-3448452d]:focus{border-color:#409eff;outline:none}.footer[data-v-3448452d]{margin-top:20px;display:flex;flex-direction:row-reverse}.btn.el-button[data-v-3448452d]{padding:10px 20px;background-color:#409eff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:16px;transition:background-color .3s ease}.btn.el-button[data-v-3448452d]:hover{background-color:#66b1ff}.guidance[data-v-3448452d]{font-size:12px;color:#909399;margin-top:5px;line-height:1.5}.form[data-v-3448452d]{margin-top:20px}.xz-input[data-v-3448452d]{border:#d9d9d9 1px solid;margin-bottom:10px;padding:5px;margin-top:5px}.aria2-tip[data-v-57ad7c2f]{padding:10px;background:rgba(0,0,0,.8);position:absolute;top:30px;left:50%;transform:translateY(-50%);color:#fff;border-radius:8px}.btns[data-v-1d4f0b89]{display:flex;flex-direction:row-reverse;padding-right:10px;padding-top:20px}.btns li[data-v-1d4f0b89]{cursor:pointer;margin-right:10px;padding:8px 15px;background-color:#409eff;color:#fff;border-radius:4px;transition:background-color .3s ease}.btns li[data-v-1d4f0b89]:hover{background-color:#66b1ff} ");
    function getPlatform() { let u = navigator.userAgent; let isAndroid = u.indexOf("Android") > -1 || u.indexOf("Adr") > -1; let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); if (isAndroid) { return "Android" } else if (isIOS) { return "IOS" } else { return "PC" } }
    var monkeyWindow = window;
    var GM_xmlhttpRequest = (() => monkeyWindow.GM_xmlhttpRequest)();
    function post(url, data, headers, type) { data = JSON.stringify(data); return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url, headers, data, responseType: type || "json", onload: (res) => { type === "blob" ? resolve(res) : res.response ? resolve(res.response || res.responseText) : reject(res) }, onerror: (err) => { reject(err) } }) }) }
    function postData(url = "", data = {}, customHeaders = {}, method = "GET") { ({ method, mode: "cors", cache: "no-cache", credentials: "same-origin", headers: { "Content-Type": "application/json", ...customHeaders }, redirect: "follow", referrerPolicy: "no-referrer" }); if (method === "GET") { return fetch(url, { method: "GET", mode: "cors", cache: "no-cache", credentials: "same-origin", headers: { "Content-Type": "application/json", ...customHeaders }, redirect: "follow", referrerPolicy: "no-referrer" }).then((response) => response.json()) } else { return new Promise((resolve, reject) => { let xhr = new XMLHttpRequest; xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(JSON.parse(xhr.response)) } else { reject({}) } } }; xhr.open(method, url); xhr.setRequestHeader("content-type", "application/json"); xhr.send(JSON.stringify(data)) }) } }
    function getHeader() { let token = ""; let captcha = ""; for (let i = 0; i < 40; i++) { let key = window.localStorage.key(i); if (key === null) break; if (key && key.startsWith("credentials")) { let tokenData = JSON.parse(window.localStorage.getItem(key)); token = tokenData.token_type + " " + tokenData.access_token; continue } if (key && key.startsWith("captcha")) { let tokenData = JSON.parse(window.localStorage.getItem(key)); captcha = tokenData.captcha_token } } return { Authorization: token, "x-device-id": window.localStorage.getItem("deviceid"), "x-captcha-token": captcha } }
    function getList(parent_id) { let url = `https://api-drive.mypikpak.com/drive/v1/files?thumbnail_size=SIZE_MEDIUM&limit=500&parent_id=${parent_id}&with_audit=true&filters=%7B%22phase%22%3A%7B%22eq%22%3A%22PHASE_TYPE_COMPLETE%22%7D%2C%22trashed%22%3A%7B%22eq%22%3Afalse%7D%7D`; return postData(url, {}, getHeader()) }
    function getDownload(id) { let header = getHeader(); return postData("https://api-drive.mypikpak.com/drive/v1/files/" + id + "?", {}, header) }
    function pushToAria(url, data) { if (["Android", "IOS"].includes(getPlatform()) && !GM_xmlhttpRequest) { return postData(url, data, {}, "POST") } else { return post(url, data, {}, "") } }
    const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val } return target };
    const _withScopeId$1 = (n) => (vue.pushScopeId("data-v-b2d19a6a"), n = n(), vue.popScopeId(), n);
    const _hoisted_1$3 = { key: 0, style: { "width": "60%" }, class: "dialog" };
    const _hoisted_2$1 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ vue.createElementVNode("h2", null, "请勾选你要下载的", -1));
    const _hoisted_3$1 = { class: "toolbar" };
    const _hoisted_4$1 = { class: "sort-options" };
    const _hoisted_5$1 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ vue.createElementVNode("label", { for: "sort-by" }, "排序方式:", -1));
    const _hoisted_6$1 = /* @__PURE__ */ vue.createStaticVNode('<option value="name" data-v-b2d19a6a>名称</option><option value="created_time" data-v-b2d19a6a>创建时间</option><option value="modified_time" data-v-b2d19a6a>修改时间</option><option value="size" data-v-b2d19a6a>大小</option><option value="file_category" data-v-b2d19a6a>文件类型</option>', 5);
    const _hoisted_11$1 = [ _hoisted_6$1 ];
    const _hoisted_12 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ vue.createElementVNode("option", { value: "asc" }, "升序", -1));
    const _hoisted_13 = /* @__PURE__ */ _withScopeId$1(() => /* @__PURE__ */ vue.createElementVNode("option", { value: "desc" }, "降序", -1));
    const _hoisted_14 = [ _hoisted_12, _hoisted_13 ];
    const _hoisted_15 = { class: "movies" };
    const _hoisted_16 = ["id", "value"];
    const _hoisted_17 = { class: "icon" };
    const _hoisted_18 = { class: "file-info" };
    const _sfc_main$3 = {
        __name: "AriaDownloadDialog", props: { show: Boolean }, emits: ["update:show", "msg"],
        setup(__props, { emit: __emit }) {
            const props = __props; const emits = __emit; const list = vue.ref([]); const selected = vue.ref([]); const checkedAll = vue.ref(false); const selectedItems = vue.ref([]); const isForbidden = vue.ref(false); const sortBy = vue.ref("name"); const sortDirection = vue.ref("asc");
            vue.watch(() => props.show, (val) => { if (val) { const tempList = []; let parent_id = window.location.href.split("/").pop(); if (parent_id == "all") parent_id = ""; emits("msg", "开始加载文件列表,请稍等"); getList(parent_id).then((res) => { res.files.forEach((item) => { tempList.push({ id: item.id, name: item.name, type: item.kind, created_time: item.created_time, modified_time: item.modified_time, size: item.size, file_category: item.file_category }) }); list.value = tempList; sortList() }) } });
            const close = () => { selected.value = []; checkedAll.value = false; isForbidden.value = false; emits("update:show", false) };
            const onCheckAll = () => { if (checkedAll.value) { selected.value = list.value.map((item, index) => index) } else { selected.value = [] } };
            const onCheck = () => { checkedAll.value = selected.value.length === list.value.length };
            const sortList = () => { list.value.sort((a, b) => { if (a.type === "drive#folder" && b.type !== "drive#folder") { return -1 } if (a.type !== "drive#folder" && b.type === "drive#folder") { return 1 } let aValue = a[sortBy.value]; let bValue = b[sortBy.value]; if (sortBy.value === "size") { aValue = parseInt(aValue); bValue = parseInt(bValue) } else if (sortBy.value === "created_time" || sortBy.value === "modified_time") { aValue = new Date(aValue).getTime(); bValue = new Date(bValue).getTime() } let comparison = 0; if (aValue > bValue) { comparison = 1 } else if (aValue < bValue) { comparison = -1 } return sortDirection.value === "asc" ? comparison : -comparison }); updateSelectedIndices() };
            const formatBytes = (bytes, decimals = 2) => { if (bytes === 0) return "0 Bytes"; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i] };
            const formatFileInfo = (item) => { switch (sortBy.value) { case "size": return item.size ? formatBytes(parseInt(item.size)) : "N/A"; case "created_time": return item.created_time ? new Date(item.created_time).toLocaleString() : "N/A"; case "modified_time": return item.modified_time ? new Date(item.modified_time).toLocaleString() : "N/A"; case "file_category": return item.file_category || "N/A"; default: return "" } };
            const updateSelectedIndices = () => { const currentlySelectedIds = new Set(selected.value.map((index) => list.value[index].id)); selected.value = []; list.value.forEach((item, index) => { if (currentlySelectedIds.has(item.id)) { selected.value.push(index) } }) };
            const getAllList = async () => { emits("msg", "开始获取文件内容"); const initialSelectedItems = []; for (const index of selected.value) { initialSelectedItems.push(list.value[index]) } const allFiles = []; const foldersToProcess = []; initialSelectedItems.forEach((item) => { if (item.type === "drive#folder") { foldersToProcess.push({ id: item.id, name: item.name, path: item.name }) } else { allFiles.push({ ...item, path: "" }) } }); let processedCount = 0; while (foldersToProcess.length > 0) { const currentFolder = foldersToProcess.shift(); processedCount++; emits("msg", `正在扫描第 ${processedCount} 个文件夹: ${currentFolder.name}`); try { const result = await getList(currentFolder.id); if (result.files) { for (const file of result.files) { if (file.kind === "drive#folder") { foldersToProcess.push({ id: file.id, name: file.name, path: `${currentFolder.path}/${file.name}` }) } else { allFiles.push({ ...file, path: currentFolder.path }) } } } } catch (e) { emits("msg", `获取文件夹 ${currentFolder.name} 内容失败`); console.error(e) } } selectedItems.value = allFiles; emits("msg", `文件获取完毕,共${allFiles.length}个文件。`) };
            const pushBefore = async () => { if (!isForbidden.value) { isForbidden.value = true; await getAllList(); push() } else { emits("msg", "任务已开始,请勿重复点击") } };

            const triggerBrowserDownload = (url, filename) => {
                const a = document.createElement('a');
                a.href = url;
                a.download = filename || 'download';
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            };

            const push = async () => {
                let total = selectedItems.value.length;
                let success = 0;
                let fail = 0;

                for (let i = 0; i < selectedItems.value.length; i++) {
                    const item = selectedItems.value[i];
                    const currentCount = i + 1;
                    
                    if (item.type === 'drive#folder') {
                        emits("msg", `[${currentCount}/${total}] 跳过文件夹: ${item.name}`);
                        continue;
                    }

                    try {
                        emits("msg", `[${currentCount}/${total}] 正在获取 ${item.name} 的链接...`);
                        const res = await getDownload(item.id);
                        if (res && res.web_content_link) {
                            triggerBrowserDownload(res.web_content_link, res.name);
                            success++;
                            await new Promise(resolve => setTimeout(resolve, 500));
                        } else {
                            fail++;
                            emits("msg", `[${currentCount}/${total}] 获取链接失败: ${item.name}`);
                            console.warn("获取下载链接失败", res);
                        }
                    } catch (err) {
                        fail++;
                        emits("msg", `[${currentCount}/${total}] 处理失败: ${item.name}`);
                        console.error("下载处理失败", err);
                    }
                }

                emits("msg", `全部任务已添加!成功: ${success},失败: ${fail}。可手动关闭窗口。`);
                
                // =======================================================================
                // --- 【核心修改】 ---
                // =======================================================================
                // 将安全锁解锁,以便开始下一次任务
                isForbidden.value = false;
                // =======================================================================
            };
            
            return (_ctx, _cache) => {
                return __props.show ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [
                    _hoisted_2$1,
                    vue.createElementVNode("div", { class: "close", onClick: close }, "×"),
                    vue.createElementVNode("div", _hoisted_3$1, [
                        vue.withDirectives(vue.createElementVNode("input", { onChange: onCheckAll, style: { "margin": "10px 10px 0 0" }, type: "checkbox", id: "checkbox", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => checkedAll.value = $event) }, null, 544), [[vue.vModelCheckbox, checkedAll.value]]),
                        vue.createTextVNode("全选 "),
                        vue.createElementVNode("div", _hoisted_4$1, [
                            _hoisted_5$1,
                            vue.withDirectives(vue.createElementVNode("select", { id: "sort-by", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => sortBy.value = $event), onChange: sortList }, _hoisted_11$1, 544), [[vue.vModelSelect, sortBy.value]]),
                            vue.withDirectives(vue.createElementVNode("select", { id: "sort-direction", "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => sortDirection.value = $event), onChange: sortList }, _hoisted_14, 544), [[vue.vModelSelect, sortDirection.value]])
                        ])
                    ]),
                    vue.createElementVNode("ul", _hoisted_15, [
                        (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(list.value, (item, index) => {
                            return vue.openBlock(), vue.createElementBlock("li", { key: item.id }, [
                                vue.withDirectives(vue.createElementVNode("input", { onChange: onCheck, type: "checkbox", id: item.id, value: index, "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => selected.value = $event) }, null, 40, _hoisted_16), [[vue.vModelCheckbox, selected.value]]),
                                vue.createElementVNode("span", _hoisted_17, vue.toDisplayString(item.type === "drive#folder" ? "📁" : "📄"), 1),
                                vue.createElementVNode("span", null, vue.toDisplayString(item.name), 1),
                                vue.createElementVNode("span", _hoisted_18, vue.toDisplayString(formatFileInfo(item)), 1)
                            ])
                        }), 128))
                    ]),
                    vue.createElementVNode("div", { class: "footer" }, [
                        vue.createElementVNode("div", { class: "btn el-button el-button--primary", onClick: pushBefore }, "浏览器下载")
                    ])
                ])) : vue.createCommentVNode("", true);
            };
        }
    };
    const AriaDownloadDialog = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-b2d19a6a"]]);
    const _withScopeId = (n) => (vue.pushScopeId("data-v-3448452d"), n = n(), vue.popScopeId(), n);
    const _hoisted_1$2 = { key: 0, style: { "width": "400px" }, class: "dialog" };
    const _hoisted_2 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("h2", null, "请配置你的aria2", -1));
    const _hoisted_3 = { class: "config-list" };
    const _hoisted_4 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("div", { class: "label" }, "RPC地址", -1));
    const _hoisted_5 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("p", { class: "guidance" }, "Aria2 RPC服务的地址,通常是 `http://127.0.0.1:6800/jsonrpc`。如果你在Docker中运行,可能需要使用宿主机的IP地址。", -1));
    const _hoisted_6 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("div", { class: "label" }, "RPC密钥", -1));
    const _hoisted_7 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("p", { class: "guidance" }, "Aria2 RPC的密钥,如果你在Aria2配置中设置了 `rpc-secret`,请在此填写。如果没有设置,请留空。", -1));
    const _hoisted_8 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("div", { class: "label" }, "下载路径", -1));
    const _hoisted_9 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("p", { class: "guidance" }, "文件在服务器上的保存路径。例如:`/downloads/` (Linux) 或 `D:\\Downloads` (Windows)\\。请确保Aria2有写入该目录的权限。", -1));
    const _hoisted_10 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("div", { class: "label" }, "其他参数", -1));
    const _hoisted_11 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("p", { class: "guidance" }, "Aria2的额外参数,以分号 `;` 分隔,例如 `user-agent=Mozilla;split=10`。这些参数会直接传递给Aria2。", -1));
    const _sfc_main$2 = { __name: "AriaConfigDialog", props: { show: Boolean }, emits: ["update:show", "msg"], setup(__props, { emit: __emit }) { const emits = __emit; const close = () => { emits("update:show", false) }; const form = vue.reactive({ host: window.localStorage.getItem("ariaHost") || "", path: window.localStorage.getItem("ariaPath") || "", token: window.localStorage.getItem("ariaToken") || "", params: window.localStorage.getItem("ariaParams") || "" }); const save = async () => { if (form.path && !form.path.endsWith("/") && !form.path.endsWith("\\")) { form.path += "/" } window.localStorage.setItem("ariaHost", form.host); window.localStorage.setItem("ariaPath", form.path); window.localStorage.setItem("ariaToken", form.token); window.localStorage.setItem("ariaParams", form.params); close(); try { const rpcUrl = form.host; const rpcToken = form.token ? `token:${form.token}` : ""; const payload = { jsonrpc: "2.0", method: "aria2.getVersion", id: 1, params: rpcToken ? [rpcToken] : [] }; const response = await pushToAria(rpcUrl, payload); if (response && response.result) { emits("msg", "保存成功!Aria2连接成功!") } else { emits("msg", "保存成功!但Aria2连接失败,请检查配置。") } } catch (error) { console.error("Aria2连接测试失败:", error); emits("msg", "保存成功!但Aria2连接失败,请检查配置。") } }; return (_ctx, _cache) => { return __props.show ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [ _hoisted_2, vue.createElementVNode("div", { class: "close", onClick: close }, "×"), vue.createElementVNode("ul", _hoisted_3, [ vue.createElementVNode("li", null, [ _hoisted_4, vue.withDirectives(vue.createElementVNode("input", { "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => form.host = $event), type: "text", placeholder: "http://127.0.0.1:6800/jsonrpc" }, null, 512), [[vue.vModelText, form.host]]), _hoisted_5 ]), vue.createElementVNode("li", null, [ _hoisted_6, vue.withDirectives(vue.createElementVNode("input", { "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => form.token = $event), type: "text", placeholder: "没有请留空" }, null, 512), [[vue.vModelText, form.token]]), _hoisted_7 ]), vue.createElementVNode("li", null, [ _hoisted_8, vue.withDirectives(vue.createElementVNode("input", { "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => form.path = $event), type: "text", placeholder: "C:/Users/admin/Downloads/" }, null, 512), [[vue.vModelText, form.path]]), _hoisted_9 ]), vue.createElementVNode("li", null, [ _hoisted_10, vue.withDirectives(vue.createElementVNode("input", { "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => form.params = $event), type: "text", placeholder: "user-agent=xxx;header=xxx" }, null, 512), [[vue.vModelText, form.params]]), _hoisted_11 ]) ]), vue.createElementVNode("div", { class: "footer" }, [ vue.createElementVNode("div", { class: "btn el-button el-button--primary", onClick: save }, "保存") ]) ])) : vue.createCommentVNode("", true) } } };
    const AriaConfigDialog = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-3448452d"]]);
    const _hoisted_1$1 = { key: 0, class: "aria2-tip" };
    const _sfc_main$1 = { __name: "Aria2Toast", setup(__props, { expose: __expose }) { const show = vue.ref(false); const open = () => { show.value = true; setTimeout(() => { show.value = false }, 3e3) }; __expose({ open }); return (_ctx, _cache) => { return show.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [ vue.renderSlot(_ctx.$slots, "default", {}, void 0, true) ])) : vue.createCommentVNode("", true) } } };
    const Aria2Toast = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-57ad7c2f"]]);
    const _hoisted_1 = { key: 0, class: "btns" };
    const _sfc_main = {
        __name: "App",
        setup(__props) {
            const downloadShow = vue.ref(false);
            const configShow = vue.ref(false);
            const tip = vue.ref("");
            const toastRef = vue.ref(null);
            const showPlugin = vue.ref(false);
            const showToast = (val) => { tip.value = val; toastRef.value.open(); };
            if (location.pathname !== "/") { showPlugin.value = true; }
            return (_ctx, _cache) => {
                return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
                    showPlugin.value ? (vue.openBlock(), vue.createElementBlock("ul", _hoisted_1, [
                        vue.createElementVNode("li", { class: "btn", onClick: _cache[0] || (_cache[0] = ($event) => downloadShow.value = true) }, "批量下载"),
                    ])) : vue.createCommentVNode("", true),
                    vue.createVNode(AriaDownloadDialog, { onMsg: showToast, show: downloadShow.value, "onUpdate:show": _cache[1] || (_cache[1] = ($event) => downloadShow.value = $event) }, null, 8, ["show"]),
                    vue.createVNode(Aria2Toast, { ref_key: "toastRef", ref: toastRef }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(tip.value), 1) ]), _: 1 }, 512)
                ], 64);
            };
        }
    };
    const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-1d4f0b89"]]);
    document.cookie = "pp_access_to_visit=true";
    setTimeout(() => { vue.createApp(App).mount((() => { let pikpakContainer = document.getElementById("app"); const app = document.createElement("div"); document.body.insertBefore(app, pikpakContainer); return app })()) }, 1e3);

})(Vue);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址