Greasy Fork

Greasy Fork is available in English.

快搭应用

快搭debug工具

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         快搭应用
// @namespace    https://yun.kujiale.com/
// @version      0.30
// @description  快搭debug工具
// @author       donghua
// @match        *.kujiale.com/pub/tool/yundesign/index*
// @match        *.kujiale.com/tool/h5/diy*
// @match        *.kujiale.com/cloud/tool/h5/diy*
// @match        *.feat.qunhequnhe.com/cloud/tool/h5/diy*
// @match        local.kujiale.com:7000/vc/flash/diy*
// @match        *.kujiale.com/pcenter/design/*/list*
// @match        */cloud/tool/h5/bim*
// @grant        none
// @run-at       document-start
// ==/UserScript==
(function () {
  'use strict';

  function getDebugData() {
    return window._KUAIDA_DEBUG;
  }

  function getReady(readyFunc) {
    return new Promise(r => {
      let value = undefined;
      let timer = setInterval(func, 500);

      function func() {
        value = readyFunc();
        if (value !== undefined) {
          clearInterval(timer);
          r(value);
        }
      }
    });
  }

  function parseUrl() {
    let str = location.search;
    str = str.slice(1);
    const data = {};
    str.split("&").forEach(keyValuePair => {
      const [key, value] = keyValuePair.split("=");
      data[key] = decodeURIComponent(value);
    });
    return data;
  }

  function stringify(data) {
    if (typeof data === "number") return String(data);
    if (!data) return "";
    if (typeof data === "string") return data;
    let ret = [];
    for (let key in data) {
      ret.push(`${key}=${encodeURIComponent(data[key])}`);
    }
    return ret.join("&");
  }

  async function getRoom(rooms, roomId) {
    return new Promise((r, j) => {
      const room = rooms.find(t => t.id === roomId);
      r(room || { name: "未找到" });
    });
  }

  function formatRoomArea(area) {
    return Number((area / 1000000).toFixed(2));
  }


  function copy(str, successCb) {
    try {
        const input = document.createElement('input');
        document.body.appendChild(input);
        input.setAttribute('value', str);
        input.select();
        document.execCommand('copy');
        document.body.removeChild(input);
        successCb && successCb();
    } catch (e) {
        // e
    }
  }


  function getLevelId() {
    return window.g_levelId;
  }

  function handleChildUse() {
      const searchValues = parseUrl();
      if (
        location.pathname.includes("/pcenter/design") &&
        searchValues.copyDesignId
      ) {
        // 方案详情
        fetch(
          `https://www.kujiale.com/dsample/api/design/copy?planid=${searchValues.copyDesignId}`,
          {
            method: "POST"
          }
        )
          .then(r => r.json())
          .then(resp => {
            if (resp.c !== "0") {
              alert(`复制接口报错:${resp.m}`);
              return;
            }
            const designId = resp.d.designId;
            const queries = {
              designid: designId,
              obsSampleId: searchValues.obsSampleId,
              roomId: searchValues.roomId,
              matchType: searchValues.matchType
            };
            const host = {
              beta: 'yun-beta.kujiale.com',
              prod: 'yun.kujiale.com'
            }[searchValues.env || 'beta'];
            location.href = `https://${host}/tool/h5/diy?${stringify(
            queries
          )}`;
          });
      }
    }

  function floorplanFit(params, successCb, failCb) {
    const { productFind, rooms, kuaidaSDK } = getDebugData();

    kuaidaSDK
      .apply({
        obsSampleId: params.obsSampleId,
        roomId: params.roomId,
        autofitMatchType: params.matchType,
      })
      .then(async (response) => {
        // 关联样板间失败情况
        if (response.relativeMatchFail) {
          alert(response.msg);
        }

        // 素材寻回 硬装不使用
        if (
          params.matchType !== 2 &&
          response.unAppliedProducts &&
          response.unAppliedProducts.length > 0
        ) {
          const room = await getRoom(rooms, params.roomId);
          productFind.setShow(true);
          productFind.setData(response.unAppliedProducts, [
            {
              id: params.roomId,
              name: (room && room.name) || params.roomId,
            },
          ]);
          productFind.setApplyId(response.applyId);
        } else {
          productFind.setShow(false);
        }

        successCb();
      })
      .catch((e) => {
        console.error(e);
        failCb && failCb();
        alert(e.message);
      });
  }

  const matchTypeMap = {
      0: "软硬装",
      1: "软装",
      2: "硬装",
      3: "饰品"
    };

  const container = document.createElement("div");
  container.style = `
  position: fixed;
  top: 20px;
  left: 30px;
  z-index: 99;
  background: white;
  padding: 5px;
  overflow: hidden;
`;

  container.innerHTML = `
  <span style="cursor: pointer;" id="kuaida-debug-toggle">收起</span> 
`;

  function* getHeight() {
    let i = 0;
    while (true) {
      const num = i % 2;
      i++;
      yield {
        0: "25px",
        1: "auto"
      }[num];
    }
  }
  const height = getHeight();

  let isAppened = false;
  function getContainer() {
    if (!isAppened) {
      document.body.appendChild(container);
      isAppened = true;

      document
        .getElementById("kuaida-debug-toggle")
        .addEventListener("click", () => {
          container.style.height = height.next().value;
        });
    }
    return container;
  }

  function handleAutofit() {
    const searchValues = parseUrl();
    getReady(() => {
      const data = getDebugData();
      if (data && data.rooms && data.rooms.length) {
        return data;
      }
    }).then(async debugData => {
      const { roomId, obsSampleId, matchType } = searchValues;
      const { rooms=[] } = debugData;
      const room = await getRoom(rooms, roomId);

      const el = document.createElement("div");
      let hasAppended = false;
      function getYuntuApp(params) {
        el.innerHTML = `
        <p>obsSampleId: ${obsSampleId}</p>
        <p>roomId: ${roomId} 房间: ${room.name} 面积:${formatRoomArea(
        room.area
      )}</p>
        <p>应用类型: ${matchTypeMap[matchType]}</p>
        <button id="kuaida-debug-btn" >${params.buttonText}</button>
        <p>${params.statusText}</p>
        <p>
          <a style="text-decoration: underline;" target="_blank" href="https://tetris.qunhequnhe.com/d/1024?c.tid=${
            params.hunterid
          }">${params.hunterid ? "查看hunter日志" : ""}</a>
        </p>
      `;
        if (!hasAppended) {
          hasAppended = true;
          getContainer().appendChild(el);
        }
        setTimeout(() => {
          document
            .querySelector("#kuaida-debug-btn")
            .addEventListener("click", apply);
        }, 0);
      }

      function apply() {
        getYuntuApp({
          statusText: "",
          buttonText: "应用中..."
        });

        floorplanFit(
          searchValues,
          () => {
            const hunterid = debugData.autofitHunterid;
            getYuntuApp({
              statusText: "应用完成",
              buttonText: "应用",
              hunterid
            });
          },
          () => {
            const hunterid = debugData.autofitHunterid;
            getYuntuApp({
              statusText: "应用失败",
              buttonText: "应用",
              hunterid
            });
          }
        );
      }

      if (roomId && matchType) {
        getYuntuApp({
          statusText: "",
          buttonText: "应用"
        });
      }
    });
  }

  function assistant() {
    getReady(() => {
      const data = getDebugData();
      if (data && data.rooms && data.rooms.length) {
        return data;
      }
    }).then(debugDaga => {
      const searchValues = parseUrl();
      const { rooms=[] } = debugDaga;
      const levelId = getLevelId();

      const el = document.createElement("div");
      el.innerHTML = `
            </br>
            <div>
                <p>
                房间:
                <select id="kuaida-debug-roomId">
                    ${rooms.map(
                      r =>
                        `<option ${
                          searchValues.roomId === r.id ? "selected" : ""
                        } value="${r.id}">${r.name} ${r.id}</option>`
                    )}
                </select>
                </p>
                <p>
                应用类型:
                <select id="kuaida-debug-matchType">
                    ${Object.keys(matchTypeMap).map(
                      type =>
                        `<option  ${
                          searchValues.matchType === type ? "selected" : ""
                        } value="${type}">${matchTypeMap[type]}</option>`
                    )}
                </select>
                </p>
                <p>
                obsSampleId:
                    <input id="kuaida-debug-obsSampleId" value="${searchValues.obsSampleId ||
                      ""}"/>
                </p>

                <p>
                <button id="kuaida-debug-copy">复制</button>
                </p>
            </div>
            </br>
        `;
      getContainer().appendChild(el);
      document
        .getElementById("kuaida-debug-copy")
        .addEventListener("click", () => {
          const roomId = document.getElementById("kuaida-debug-roomId").value;
          const matchType = document.getElementById("kuaida-debug-matchType")
            .value;
          const obsSampleId = document.getElementById("kuaida-debug-obsSampleId")
            .value;
          const params = {
            obsSampleId,
            levelId,
            obsDesignId: window.g_designId,
            roomId,
            lang: "zh_CN",
            obsUserId: window.g_flashCfg.appConfig.userConfig.userId,
            autofitMatchType: matchType,
            obsRelativeSampleRoomIds: []
          };

          console.log(params);
          copy(JSON.stringify(params, null, 2), () => {
            alert("复制成功");
          });
        });
    });
  }

  // 标识需要debug
  window.jlfajkdjfklsdjl = true;

  (function() {
    // 子账号复现
    handleChildUse();
    // 快速应用
    handleAutofit();
    // 辅助功能
    assistant();
  })();

}());