monkey-yunxiao

云效脚本

目前为 2024-08-12 提交的版本。查看 最新版本

// ==UserScript==
// @name         monkey-yunxiao
// @namespace    npm/vite-plugin-monkey
// @version      0.0.4.1
// @author       monkey
// @description  云效脚本
// @license      MIT
// @icon         data:image/svg+xml,%3Csvg%20width%3D%22240%22%20height%3D%22240%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cdefs%3E%3ClinearGradient%20x1%3D%2250.007%25%22%20y1%3D%2299.839%25%22%20x2%3D%2250.007%25%22%20y2%3D%22.339%25%22%20id%3D%22a%22%3E%3Cstop%20stop-color%3D%22%23006ad4%22%20stop-opacity%3D%22.5%22%20offset%3D%220%25%22%2F%3E%3Cstop%20stop-color%3D%22%23006ad4%22%20stop-opacity%3D%22.2%22%20offset%3D%22100%25%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20x1%3D%2250.035%25%22%20y1%3D%22-.079%25%22%20x2%3D%2250.035%25%22%20y2%3D%2299.929%25%22%20id%3D%22b%22%3E%3Cstop%20stop-color%3D%22%23006ad4%22%20offset%3D%220%25%22%2F%3E%3Cstop%20stop-color%3D%22%23006ad4%22%20stop-opacity%3D%22.5%22%20offset%3D%22100%25%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20width%3D%22240%22%20height%3D%22240%22%20rx%3D%2212%22%2F%3E%3Cg%20transform%3D%22translate(24%2024)%22%20fill-rule%3D%22nonzero%22%3E%3Cpath%20d%3D%22m192%20191.774-67.621-89.901%2048.997-67.087-33.921-26.202-69.395%2093.74%2060.748%2080.64c4.213%205.648%2010.642%208.81%2017.737%208.81H192Z%22%20fill%3D%22url(%23a)%22%2F%3E%3Cellipse%20fill%3D%22%23006ad4%22%20cx%3D%22156.527%22%20cy%3D%2221.685%22%20rx%3D%2221.284%22%20ry%3D%2221.685%22%2F%3E%3Cpath%20d%3D%22M124.379%20101.873%2061.413%2018.296c-4.212-5.647-10.642-8.809-17.736-8.809H0l69.838%2092.838L3.77%20192h43.012c7.094%200%2013.524-3.388%2017.736-9.035l59.862-81.092Z%22%20fill%3D%22url(%23b)%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E
// @match        https://devops.aliyun.com/projex/*
// @match        https://devops.aliyun.com/workbench*
// @require      https://lf9-cdn-tos.bytecdntp.com/cdn/expire-10-y/rxjs/7.5.4/rxjs.umd.min.js
// @grant        GM_addStyle
// ==/UserScript==

(t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const e=document.createElement("style");e.textContent=t,document.head.append(e)})(" ._status-button-progress_1wcb5_1{position:absolute;bottom:0;left:0;width:100%;height:2px;background:red;transition:width .5s} ");

(function (rxjs) {
  'use strict';

  var __defProp = Object.defineProperty;
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
  const style = {
    "status-button-progress": "_status-button-progress_1wcb5_1"
  };
  const match = (path) => {
    return (
      // 任务视图
      /^\/projex\/project\/.+\/task/.test(path) || // 工作项视图
      /^\/projex\/workitem/.test(path) || // 工作台视图
      /^\/workbench$/.test(path)
    );
  };
  const apiMaps = /* @__PURE__ */ new Map([
    [
      "/projex/api/workitem/workitem/list",
      (data) => {
        rxjs.interval(100).pipe(
          // 查询到元素存在后,停止轮询,并返回元素
          rxjs.map(() => {
            let dom = document.querySelector(
              "#AONE_MY_WORKITEM_CARD .next-table-inner"
            );
            let col = 1;
            if (dom) {
              return {
                dom,
                col
              };
            }
            dom = document.querySelector(
              ".workitemListMainAreaWrap .next-table-inner"
            );
            if (dom) {
              col = findColsNum(dom, "状态");
              return {
                dom,
                col
              };
            }
            return void 0;
          }),
          rxjs.first((data2) => !!data2),
          rxjs.takeUntil(rxjs.timer(500))
        ).subscribe({
          next: ({ dom: target, col }) => {
            if (target.getAttribute("init-progress")) {
              console.log("已经初始化过了");
              return;
            }
            target.setAttribute("init-progress", "true");
            if (col) {
              const elList = target.querySelectorAll(
                `.next-table-body tr td[data-next-table-col="${col}"] button`
              );
              elList.forEach((el, i) => {
                const dataItem = data.result[i];
                if (dataItem.workitemType.name !== "任务") return;
                el.style.position = "relative";
                const div = document.createElement("div");
                div.classList.add(style["status-button-progress"]);
                el.appendChild(div);
                const parentIdentifier = dataItem == null ? void 0 : dataItem.parentIdentifier;
                parentIdentifier && queryParentAndUpdateEl(parentIdentifier, div, dataItem);
              });
            }
          }
        });
      }
    ]
  ]);
  function findColsNum(target, title) {
    const thList = target.querySelectorAll(
      ".next-table-header th"
    );
    for (let i = 0; i < thList.length; i++) {
      if (thList[i].innerText === title) {
        return i;
      }
    }
    return void 0;
  }
  async function queryParentAndUpdateEl(identifier, dom, dataItem) {
    var _a;
    const res = await fetch(
      `https://devops.aliyun.com/projex/api/workitem/v2/workitem/${identifier}/relation/workitem/list/by-relation-category?category=PARENT_SUB&isForward=true&_input_charset=utf-8`,
      {
        headers: {
          "Content-Type": "application/json"
        },
        method: "GET",
        credentials: "include"
      }
    ).then((res2) => res2.json());
    const taskList = (_a = res.result) == null ? void 0 : _a.filter((item) => item.workitemTypeName === "任务").filter((item) => item.identifier !== dataItem.identifier);
    function setStyle(n) {
      dom.style.width = `${n}%`;
    }
    if (!(taskList == null ? void 0 : taskList.length)) {
      setStyle(100);
      return;
    }
    const progress = taskList.length * 100;
    let completed = 0;
    taskList.forEach((task) => {
      var _a2;
      const progressStr = (_a2 = task.fieldValueVOList.find(
        (field) => field.fieldIdentifier === "progress"
      )) == null ? void 0 : _a2.value;
      if (progressStr === "0.1") return;
      const n = Number(progressStr);
      if (n) {
        completed += n;
      }
    });
    const percent = completed / progress * 100;
    setStyle(percent);
  }
  const name = "任务进度条";
  const taskHandler = {
    match,
    apiMaps,
    name
  };
  class ChainOfResponsibility {
    constructor() {
      __publicField(this, "handlers");
      this.handlers = [];
    }
    add(handler) {
      this.handlers.push(handler);
      return this;
    }
    handleApi(params) {
      for (const handler of this.handlers) {
        if (handler.match(params.triggerURLPath)) {
          const task = handler.apiMaps.get(params.path);
          if (task) {
            console.log(`通过接口请求,触发了脚本: ${params.path} ===> ${handler.name}`);
            task(params.responseJSON);
          }
        }
      }
    }
  }
  const chain = new ChainOfResponsibility();
  chain.add(taskHandler);
  const xhrOpen = window.XMLHttpRequest.prototype.open;
  window.XMLHttpRequest.prototype.open = function(...args) {
    xhrOpen.apply(this, args);
    let triggerURLPath = location.pathname;
    this.addEventListener("readystatechange", function() {
      if (this.readyState === 4) {
        const path = new URL(this.responseURL).pathname;
        const responseJSON = this.responseType === "json" ? this.response : JSON.parse(this.responseText);
        chain.handleApi({
          path,
          responseJSON,
          triggerURLPath
        });
      }
    });
  };

})(rxjs);

QingJ © 2025

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