🔥🔥360图书馆文件内容图片一键复制下载🔥🔥

360图书馆文件内容复制到剪贴板,暂时不支持复制文章里面的图

ของเมื่อวันที่ 03-02-2024 ดู เวอร์ชันล่าสุด

// ==UserScript==
// @name         🔥🔥360图书馆文件内容图片一键复制下载🔥🔥
// @namespace    https://www.softrr.cn/
// @version      2.0.0
// @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      https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/clipboard.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/index.full.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/index.css
// @connect      www.softrr.cn
// @grant        GM.getValue
// @grant        GM_addStyle
// @grant        GM_download
// @grant        GM_setValue
// @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-8d4508d1]{width:200px;position:fixed;left:10px;top:80px}.copy .pos[data-v-8d4508d1]{position:relative}.copy .pos .btn[data-v-8d4508d1]{background-color:red}.copy .pos .btn[data-v-8d4508d1]:hover{background-color:#00ff48}.copy .pos .content[data-v-8d4508d1]{position:absolute;left:110px;top:0;background-color:#ffb700}.copy .pos .content[data-v-8d4508d1]:hover{background-color:#00ff48}.copy .pos .down[data-v-8d4508d1]{position:absolute;left:110px;top:83px;background-color:#8000ff}.copy .pos .down[data-v-8d4508d1]:hover{background-color:#00ff48}button[data-v-8d4508d1]{color:#fff;width:45%;height:60px;font-size:16px;text-align:center} ");

(function (vue, Clipboard, JSZip, axios, elementPlus) {
  'use strict';

  var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
  function getDefaultExportFromCjs(x) {
    return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
  }
  var FileSaver_min = { exports: {} };
  (function(module, exports) {
    (function(a, b) {
      b();
    })(commonjsGlobal, function() {
      function b(a2, b2) {
        return "undefined" == typeof b2 ? b2 = { autoBom: false } : "object" != typeof b2 && (console.warn("Deprecated: Expected third argument to be a object"), b2 = { autoBom: !b2 }), b2.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a2.type) ? new Blob(["\uFEFF", a2], { type: a2.type }) : a2;
      }
      function c(a2, b2, c2) {
        var d2 = new XMLHttpRequest();
        d2.open("GET", a2), d2.responseType = "blob", d2.onload = function() {
          g(d2.response, b2, c2);
        }, d2.onerror = function() {
          console.error("could not download file");
        }, d2.send();
      }
      function d(a2) {
        var b2 = new XMLHttpRequest();
        b2.open("HEAD", a2, false);
        try {
          b2.send();
        } catch (a3) {
        }
        return 200 <= b2.status && 299 >= b2.status;
      }
      function e(a2) {
        try {
          a2.dispatchEvent(new MouseEvent("click"));
        } catch (c2) {
          var b2 = document.createEvent("MouseEvents");
          b2.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null), a2.dispatchEvent(b2);
        }
      }
      var f = "object" == typeof window && window.window === window ? window : "object" == typeof self && self.self === self ? self : "object" == typeof commonjsGlobal && commonjsGlobal.global === commonjsGlobal ? commonjsGlobal : void 0, a = f.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent), g = f.saveAs || ("object" != typeof window || window !== f ? function() {
      } : "download" in HTMLAnchorElement.prototype && !a ? function(b2, g2, h) {
        var i = f.URL || f.webkitURL, j = document.createElement("a");
        g2 = g2 || b2.name || "download", j.download = g2, j.rel = "noopener", "string" == typeof b2 ? (j.href = b2, j.origin === location.origin ? e(j) : d(j.href) ? c(b2, g2, h) : e(j, j.target = "_blank")) : (j.href = i.createObjectURL(b2), setTimeout(function() {
          i.revokeObjectURL(j.href);
        }, 4e4), setTimeout(function() {
          e(j);
        }, 0));
      } : "msSaveOrOpenBlob" in navigator ? function(f2, g2, h) {
        if (g2 = g2 || f2.name || "download", "string" != typeof f2)
          navigator.msSaveOrOpenBlob(b(f2, h), g2);
        else if (d(f2))
          c(f2, g2, h);
        else {
          var i = document.createElement("a");
          i.href = f2, i.target = "_blank", setTimeout(function() {
            e(i);
          });
        }
      } : function(b2, d2, e2, g2) {
        if (g2 = g2 || open("", "_blank"), g2 && (g2.document.title = g2.document.body.innerText = "downloading..."), "string" == typeof b2)
          return c(b2, d2, e2);
        var h = "application/octet-stream" === b2.type, i = /constructor/i.test(f.HTMLElement) || f.safari, j = /CriOS\/[\d]+/.test(navigator.userAgent);
        if ((j || h && i || a) && "undefined" != typeof FileReader) {
          var k = new FileReader();
          k.onloadend = function() {
            var a2 = k.result;
            a2 = j ? a2 : a2.replace(/^data:[^;]*;/, "data:attachment/file;"), g2 ? g2.location.href = a2 : location = a2, g2 = null;
          }, k.readAsDataURL(b2);
        } else {
          var l = f.URL || f.webkitURL, m = l.createObjectURL(b2);
          g2 ? g2.location = m : location.href = m, g2 = null, setTimeout(function() {
            l.revokeObjectURL(m);
          }, 4e4);
        }
      });
      f.saveAs = g.saveAs = g, module.exports = g;
    });
  })(FileSaver_min);
  var FileSaver_minExports = FileSaver_min.exports;
  const FileSaver = /* @__PURE__ */ getDefaultExportFromCjs(FileSaver_minExports);
  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$1 = { 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$1, [
              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 _hoisted_1 = { class: "pos" };
  const _hoisted_2 = { class: "btnGroup" };
  const _hoisted_3 = ["data-clipboard-text"];
  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;
        }
      });
      var imgList = document.querySelector("#artContent").querySelectorAll("img");
      const onContent = () => {
        const clipboard = new Clipboard(".content");
        showFlag.value = false;
        clipboard.on("success", () => {
          elementPlus.ElMessage({
            message: "复制成功",
            type: "success"
          });
          clipboard.destroy();
        });
        clipboard.on("error", () => {
          elementPlus.ElMessage({
            message: "复制失败",
            type: "warning"
          });
          clipboard.destroy();
        });
      };
      const onImage = () => {
        downloadZip();
      };
      const downloadZip = () => {
        const zip = new JSZip();
        const promises = [];
        imgList.forEach((item) => {
          if (item.src.includes("default"))
            return;
          const promise = new Promise((resolve, reject) => {
            axios({
              url: item.src,
              method: "GET",
              responseType: "arraybuffer"
            }).then((res) => {
              resolve(res);
            }).catch((error) => {
              reject(error);
            });
          }).then((res) => {
            let fileName = Date.now();
            const base64String = btoa(
              new Uint8Array(res.data).reduce((data, byte) => data + String.fromCharCode(byte), "")
            );
            zip.file(fileName + ".jpg", base64String, { base64: true });
          });
          promises.push(promise);
        });
        Promise.all(promises).then(() => {
          zip.generateAsync({
            type: "blob",
            compression: "DEFLATE",
            // STORE:默认不压缩 DEFLATE:需要压缩
            compressionOptions: {
              level: 9
              // 压缩等级1~9    1压缩速度最快,9最优压缩方式
            }
          }).then((res) => {
            FileSaver.saveAs(res, "图片下载结果.zip");
          });
        });
      };
      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",
                "data-clipboard-text": response1.value
              }, " 内容 复制 ", 8, _hoisted_3), [
                [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-8d4508d1"]]);
  vue.createApp(App).mount(
    (() => {
      const app = document.createElement("div");
      document.body.append(app);
      return app;
    })()
  );

})(Vue, clipboard, jszip, axios, element-plus);