// ==UserScript==
// @name 🔥🔥360图书馆文件内容图片一键复制下载🔥🔥
// @namespace https://www.softrr.cn/
// @version 2.0.6
// @author hackhase
// @description 360图书馆文件内容复制到剪贴板,支持一键下载文章里面的图片
// @license MIT
// @icon http://pubimage.360doc.com/index7/nlogo.jpg
// @match http://www.360doc.com/content/*
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js
// @require data:application/javascript,%3Bwindow.Vue%3DVue%3B
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/index.full.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js
// @resource element-plus/dist/index.css https://cdn.jsdelivr.net/npm/[email protected]/dist/index.css
// @connect www.softrr.cn
// @run-at document-start
// @grant GM_addStyle
// @grant GM_getResourceText
// @grant GM_setClipboard
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// ==/UserScript==
(o=>{if(typeof GM_addStyle=="function"){GM_addStyle(o);return}const t=document.createElement("style");t.textContent=o,document.head.append(t)})(" :root{font-family:Inter,Avenir,Helvetica,Arial,sans-serif;font-size:16px;line-height:24px;font-weight:400;color-scheme:light dark;color:#ffffffde;background-color:#242424;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}body{margin:0;place-items:center;min-width:320px;min-height:100vh}h1{font-size:3.2em;line-height:1.1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}.card{padding:2em}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}.modal-wrapper[data-v-28b335ec]{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center;z-index:999}.modal[data-v-28b335ec]{background-color:#fff;padding:20px;border-radius:5px}.header[data-v-28b335ec]{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}.header h2[data-v-28b335ec]{margin:0;font-size:20px;font-weight:700}.header button[data-v-28b335ec]{border:none;background-color:transparent;font-size:20px;cursor:pointer}.content[data-v-28b335ec]{max-height:400px;overflow:auto;font-size:16px;display:flex;justify-content:space-between}.content .produce p[data-v-28b335ec]{margin-top:15px}.content .produce .ipt[data-v-28b335ec]{margin-top:15px;height:30px;border-radius:5px;padding-left:10px}.content .img[data-v-28b335ec]{display:flex;align-items:center;justify-content:center}.content .img img[data-v-28b335ec]{width:180px}input[data-v-28b335ec]::-webkit-input-placeholder{color:#aab2bd;font-size:14px;padding-left:5px}.copy[data-v-e21b77ff]{width:200px;position:fixed;left:10px;top:80px}.copy .pos[data-v-e21b77ff]{position:relative}.copy .pos .btn[data-v-e21b77ff]{background-color:red}.copy .pos .btn[data-v-e21b77ff]:hover{background-color:#00ff48}.copy .pos .content[data-v-e21b77ff]{position:absolute;left:110px;top:0;background-color:#ffb700}.copy .pos .content[data-v-e21b77ff]:hover{background-color:#00ff48}.copy .pos .down[data-v-e21b77ff]{position:absolute;left:110px;top:83px;background-color:#8000ff}.copy .pos .down[data-v-e21b77ff]:hover{background-color:#00ff48}button[data-v-e21b77ff]{color:#fff;width:45%;height:60px;font-size:16px;text-align:center} ");
(function (vue, elementPlus, JSZip) {
'use strict';
var _GM_setClipboard = /* @__PURE__ */ (() => typeof GM_setClipboard != "undefined" ? GM_setClipboard : void 0)();
var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _withScopeId = (n) => (vue.pushScopeId("data-v-28b335ec"), n = n(), vue.popScopeId(), n);
const _hoisted_1$1 = { class: "modal" };
const _hoisted_2$1 = { class: "header" };
const _hoisted_3 = { class: "content" };
const _hoisted_4 = { class: "produce" };
const _hoisted_5 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("p", null, "1、扫描右侧公众号,点击关注!", -1));
const _hoisted_6 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("p", null, "2、在软件爬取者后台回复:验证码", -1));
const _hoisted_7 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("p", null, "3、在下方输入框输入获取的验证码后回车", -1));
const _hoisted_8 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("div", { class: "img" }, [
/* @__PURE__ */ vue.createElementVNode("img", {
src: "https://www.softrr.cn/assets/pqz-daa4b840.jpg",
alt: ""
})
], -1));
const _sfc_main$1 = {
__name: "Model",
props: {
title: {
type: String,
required: true
},
code: {
type: Number
}
},
setup(__props, { expose: __expose }) {
const props = __props;
const visible = vue.ref(false);
const openModal = () => {
visible.value = true;
};
const closeModal = () => {
visible.value = false;
};
__expose({
visible,
openModal,
closeModal
});
const codeValue = vue.ref();
const enterCode = () => {
if (codeValue.value == props.code) {
localStorage.setItem("code", codeValue.value);
visible.value = false;
alert("验证成功,请再次点击解析!");
codeValue.value = "";
} else {
alert("验证码错误,请重新输入!");
codeValue.value = "";
}
};
return (_ctx, _cache) => {
return vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", {
class: "modal-wrapper",
onClick: vue.withModifiers(closeModal, ["self"])
}, [
vue.createElementVNode("div", _hoisted_1$1, [
vue.createElementVNode("div", _hoisted_2$1, [
vue.createElementVNode("h2", null, vue.toDisplayString(__props.title), 1),
vue.createElementVNode("button", { onClick: closeModal }, "X")
]),
vue.createElementVNode("div", _hoisted_3, [
vue.createElementVNode("div", _hoisted_4, [
_hoisted_5,
_hoisted_6,
_hoisted_7,
vue.withDirectives(vue.createElementVNode("input", {
class: "ipt",
type: "text",
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => codeValue.value = $event),
onKeydown: vue.withKeys(enterCode, ["enter"]),
placeholder: "请输入验证码后按回车"
}, null, 544), [
[vue.vModelText, codeValue.value]
])
]),
_hoisted_8
])
])
], 512)), [
[vue.vShow, visible.value]
]);
};
}
};
const Model = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-28b335ec"]]);
const getFile = (url) => {
return new Promise((resolve, reject) => {
let xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.responseType = "blob";
xmlhttp.onload = function() {
if (this.status == 200) {
resolve(this.response);
} else {
reject(this.status);
}
};
xmlhttp.send();
});
};
const downFile = async (arrList) => {
console.log(arrList);
const zip = new JSZip();
const cache = {};
const promises = [];
await arrList.forEach((item) => {
const promise = getFile(item.src).then((data) => {
const lst = item.src.split(".");
const fileType = lst[lst.length - 1];
zip.file(Date.now() + "." + fileType, data, { binary: true });
cache[item.fileName] = data;
});
promises.push(promise);
});
Promise.all(promises).then(() => {
zip.generateAsync({ type: "blob" }).then((content) => {
downLoad(content, "模板下载", "zip");
});
});
};
const downLoad = (blob, name, type) => {
if (!blob || !type)
return;
const url = window.URL || window.webkitURL || window.moxURL;
const downloadHref = url.createObjectURL(blob);
const link = document.createElement("a");
link.href = downloadHref;
link.download = `${name || "导出文件"}.${type}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
url.revokeObjectURL(downloadHref);
};
const _hoisted_1 = { class: "pos" };
const _hoisted_2 = { class: "btnGroup" };
const _sfc_main = {
__name: "App",
setup(__props) {
var a_left = document.querySelector(".a_left");
a_left.style.zIndex = 0;
const code = vue.ref();
_GM_xmlhttpRequest({
method: "GET",
url: `https://www.softrr.cn/crawler/getCode`,
headers: {
Referer: "https://www.softrr.cn/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36"
},
onload: function(res) {
code.value = JSON.parse(res.response).data[0].code;
}
});
const url = window.location.href;
const response1 = vue.ref("");
_GM_xmlhttpRequest({
method: "GET",
url: `https://www.softrr.cn/crawler/copy360?url=${url}`,
headers: {
Referer: "http://www.360doc.com/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/537.36"
},
onload: function(res) {
response1.value = JSON.parse(res.response).data;
}
});
const btnGroupRef = vue.ref();
const showFlag = vue.ref(false);
const handler = (e) => {
if (btnGroupRef.value) {
if (btnGroupRef.value.contains(e.target)) {
showFlag.value = true;
} else {
showFlag.value = false;
}
}
};
document.addEventListener("click", handler);
vue.onUnmounted(() => {
document.removeEventListener("click", handler);
});
const title = vue.ref("为了减少端口压力,防止滥用,采取必要的验证手段。");
const model = vue.ref("");
const onSelect = () => {
let locaCode = localStorage.getItem("code") || "";
if (locaCode == code.value) {
showFlag.value = true;
} else {
showFlag.value = false;
model.value.openModal();
}
};
vue.watch(showFlag, (newV, oldV) => {
let locaCode = localStorage.getItem("code") || "";
if (locaCode != code.value) {
showFlag.value = false;
}
});
const onContent = () => {
showFlag.value = false;
_GM_setClipboard(response1.value, "text", () => {
if (response1.value) {
elementPlus.ElMessage.success("复制成功");
} else {
elementPlus.ElMessage.warning("复制失败");
}
});
};
var imgList = document.querySelector("#artContent").querySelectorAll("img");
const onImage = () => {
downLoad2();
};
const downLoad2 = () => {
let list = [];
imgList.forEach((item) => {
if (item.src.includes("default"))
return;
if (item.src) {
list.push(item);
}
});
if (list.length === 0) {
elementPlus.ElMessage({
type: "info",
message: "请至少选择一个文件下载"
});
return;
}
downFile(list);
};
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("div", {
class: "copy",
ref_key: "btnGroupRef",
ref: btnGroupRef
}, [
vue.createElementVNode("div", _hoisted_1, [
vue.createElementVNode("button", {
onClick: vue.withModifiers(onSelect, ["stop", "prevent"]),
class: "btn"
}, "选择"),
vue.createElementVNode("div", _hoisted_2, [
vue.withDirectives(vue.createElementVNode("button", {
onClick: onContent,
class: "content"
}, "内容 复制", 512), [
[vue.vShow, showFlag.value]
]),
vue.withDirectives(vue.createElementVNode("button", {
onClick: onImage,
class: "down"
}, "图片 下载", 512), [
[vue.vShow, showFlag.value]
])
]),
vue.createVNode(Model, {
title: title.value,
code: code.value,
ref_key: "model",
ref: model
}, null, 8, ["title", "code"])
])
], 512);
};
}
};
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-e21b77ff"]]);
const cssLoader = (e) => {
const t = GM_getResourceText(e);
return GM_addStyle(t), t;
};
cssLoader("element-plus/dist/index.css");
vue.createApp(App).mount(
(() => {
const app = document.createElement("div");
document.body.append(app);
return app;
})()
);
const addScript = (src) => {
return new Promise((resolve, reject) => {
const s = document.createElement("script");
s.setAttribute("src", src);
s.addEventListener("load", resolve);
s.addEventListener("error", reject);
var head = document.getElementsByTagName("head")[0];
head.appendChild(s);
});
};
const loadLibrary = async () => {
await addScript("https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js");
};
loadLibrary();
})(Vue, ElementPlus, jszip);