Greasy Fork

Greasy Fork is available in English.

剧本杀活动通知生成器

用于获取本周剧本杀活动信息并生成 Markdown 代码

当前为 2024-07-03 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         剧本杀活动通知生成器
// @namespace    https://github.com/heiyexing
// @version      2024-07-03
// @description  用于获取本周剧本杀活动信息并生成 Markdown 代码
// @author       炎熊
// @match        https://yuque.antfin-inc.com/yuhmb7/pksdw8/**
// @match        https://yuque.antfin.com/yuhmb7/pksdw8/**
// @icon         https://www.google.com/s2/favicons?sz=64&domain=antfin-inc.com
// @require      https://registry.npmmirror.com/dayjs/1.11.9/files/dayjs.min.js
// @require      https://registry.npmmirror.com/dayjs/1.11.9/files/plugin/isSameOrAfter.js
// @require      https://registry.npmmirror.com/dayjs/1.11.9/files/plugin/isSameOrBefore.js
// @require      https://registry.npmmirror.com/dayjs/1.11.9/files/locale/zh-cn.min.js
// @require      https://www.layuicdn.com/layui-v2.8.0/layui.js
// @run-at       document-end
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
  "use strict";

  dayjs.locale(dayjs_locale_zh_cn);
  dayjs.extend(dayjs_plugin_isSameOrAfter);
  dayjs.extend(dayjs_plugin_isSameOrBefore);

  const BTN_ID = "murder-mystery-btn";
  const USER_LIST_CLASS_NAME = "murder-user-list";
  const USER_ITEM_CLASS_NAME = "murder-user-item";

  let timeRange = [dayjs().startOf("week"), dayjs().endOf("week")];

  function initStyle() {
    const style = document.createElement("style");
    style.innerHTML = `
                      #${BTN_ID} {
                          position: fixed;
                          bottom: 25px;
                          right: 80px;
                          width: 40px;
                          height: 40px;
                          background-color: #fff;
                          border-radius: 50%;
                          box-shadow: 0 0 10px rgba(0, 0, 0, .2);
                          cursor: pointer;
                          display: inline-flex;
                          justify-content: center;
                          align-items: center;
                          z-index: 2;
                      }
                      #${BTN_ID} img {
                          width: 20px;
                      }
                      .${USER_LIST_CLASS_NAME} {
                        display: flex;
                        flex-wrap: wrap;
                      }
                      .${USER_ITEM_CLASS_NAME} {
                        margin-right: 12px;
                        margin-bottom: 12px;
                        display: flex;
                        justify-content: space-between;
                        align-items: center;
                        flex-wrap: wrap;
                        line-height: 14px;
                        border-radius: 6px;
                        padding: 6px;
                        border: 1px solid #E7E9E8;
                      }
                      .${USER_ITEM_CLASS_NAME}.unchecked {
                        border-color: #ff0000;
                      }
                      .${USER_ITEM_CLASS_NAME} span {
                        white-space: nowrap;
                      }
                      .${USER_ITEM_CLASS_NAME} img {
                        width: 30px;
                        height: 30px;
                        border-radius: 30px;
                        margin-right: 6px;
                      }
                      .layui-card-body {
                        width: 100%;
                      }
                      .layui-card-footer {
                        display: flex;
                        justify-content: space-between;
                        align-items: center;
                      }
                      `;
    const link = document.createElement("link");
    link.setAttribute("rel", "stylesheet");
    link.setAttribute("type", "text/css");
    link.href =
      "https://cdn.bootcdn.net/ajax/libs/layui/2.8.17/css/layui.min.css";
    document.head.appendChild(style);
    document.head.appendChild(link);
    return style;
  }

  function initBtn() {
    const btn = document.createElement("div");
    btn.id = BTN_ID;
    const logo = document.createElement("img");
    logo.src =
      "https://mdn.alipayobjects.com/huamei_baaa7a/afts/img/A*f8MvQYdbHPoAAAAAAAAAAAAADqSCAQ/original";
    btn.appendChild(logo);
    document.body.appendChild(btn);
    return btn;
  }

  function getTitleInfo(title) {
    const month = title.match(/\d+(?=\s*月)/)?.[0];
    const date = title.match(/\d+(?=\s*日)/)?.[0];
    const name = title.match(/(?<=《).*?(?=》)/)?.[0];
    if (!month || !date || !name) {
      return null;
    }
    return {
      month: +month,
      date: +date,
      name,
    };
  }

  function getRegExpStr(strList, regexp) {
    for (const str of strList) {
      const result = str.match(regexp);
      if (result) {
        return result[0].trim();
      }
    }
    return "";
  }

  function downloadFile(content, fileName) {
    const url = `data:text/csv;charset=utf-8,\ufeff${encodeURIComponent(
      content
    )}`;
    // 创建a标签
    const link = document.createElement("a");
    link.href = url;
    link.download = fileName;
    link.click();
  }

  function exeCommandCopyText(text) {
    try {
      const t = document.createElement("textarea");
      t.nodeValue = text;
      t.value = text;
      document.body.appendChild(t);
      t.select();
      document.execCommand("copy");
      document.body.removeChild(t);
      return true;
    } catch (e) {
      console.log(e);
      return false;
    }
  }

  function getInnerText(content) {
    const div = document.createElement("div");
    div.style = "height: 0px; overflow: hidden;";
    div.innerHTML = content;
    document.body.appendChild(div);
    return div.innerText;
  }

  function chineseToArabic(chineseNum) {
    let num = chineseNum
      .replace(/零/g, "0")
      .replace(/一/g, "1")
      .replace(/二/g, "2")
      .replace(/三/g, "3")
      .replace(/四/g, "4")
      .replace(/五/g, "5")
      .replace(/六/g, "6")
      .replace(/七/g, "7")
      .replace(/八/g, "8")
      .replace(/九/g, "9");
    num = num
      .replace(/十/g, "10")
      .replace(/百/g, "100")
      .replace(/千/g, "1000")
      .replace(/万/g, "10000");
    return num;
  }

  async function getAllActivesInfo() {
    if (!window.appData || !Array.isArray(window.appData?.book.toc)) {
      return;
    }
    const tocList = window.appData?.book.toc.filter((item) =>
      ["BkpJsZ1b7Xm9MB8p", "_yvlr38511LXSB_-"].includes(item.parent_uuid)
    );

    return tocList;
  }

  async function getActivesInfo(start, end) {
    if (!window.appData || !Array.isArray(window.appData?.book.toc)) {
      return;
    }
    const tocList = window.appData?.book.toc;
    const pathList = location.pathname.split("/");
    if (pathList.length <= 0) {
      return;
    }
    const docUrl = pathList[pathList.length - 1];
    const currentToc = tocList.find((item) => item.url === docUrl);
    if (!currentToc) {
      return;
    }
    const parentToc = tocList.find(
      (item) => item.uuid === currentToc.parent_uuid
    );
    if (!parentToc) {
      return;
    }
    const targetTocList = tocList.filter(
      (item) => item.parent_uuid === parentToc.uuid
    );

    const targetTimeRangeList = targetTocList
      .map((item) => {
        const titleInfo = getTitleInfo(item.title);
        if (!titleInfo) {
          return item;
        }
        return {
          ...item,
          ...titleInfo,
          dayjs: dayjs()
            .set("month", titleInfo.month - 1)
            .set("date", titleInfo.date),
        };
      })
      .filter((item) => {
        return (
          item.dayjs.isSameOrAfter(start, "date") &&
          item.dayjs.isSameOrBefore(end, "date")
        );
      })
      .sort((a, b) => a.dayjs - b.dayjs);

    return await Promise.all(
      targetTimeRangeList.map((item) => {
        return fetch(
          `${location.origin}/api/docs/${item.url}?book_id=${window.appData?.book.id}&include_contributors=true&include_like=true&include_hits=true&merge_dynamic_data=false`
        )
          .then((res) => res.json())
          .then((res) => {
            const rowList = getInnerText(res.data.content).split("\n");

            const tag = getRegExpStr(rowList, /(?<=类型\s*[::]\s*).+/)
              ?.split(/[/||]/)
              .join("/");

            const level = getRegExpStr(
              rowList,
              /(?<=(难度|适合)\s*[::\s*]).+/
            );

            const dm = getRegExpStr(rowList, /(?<=(dm|DM)\s*[::]\s*).+/);

            let place = getRegExpStr(rowList, /(?<=(地点|场地)\s*[::]\s*).+/);

            if (/[Aa]\s?空间/.test(place)) {
              place = "A空间";
            }
            if (/元空间/.test(place)) {
              place = "元空间";
            }

            const persons = getRegExpStr(rowList, /(?<=(人数)\s*[::]\s*).+/)
              .split(/[,,\(\)()「」]/)
              .map((item) => item.replace(/(回复报名|注明男女|及人数)/, ""))
              .filter((item) => item.trim())
              .join("·");

            const manCount = +persons.match(/(\d+)\s?男/)?.[1] || undefined;
            const womanCount = +persons.match(/(\d+)\s?女/)?.[1] || undefined;
            const personCount = (() => {
              if (manCount && womanCount) {
                return manCount + womanCount;
              }
              if (/(\d+)[~~到-](\d+)/.test(persons.replace(/\s/g, ""))) {
                return +/(\d+)[~~到-](\d+)/.exec(
                  persons.replaceAll(" ", "")
                )[1];
              }
              if (/(\d+)人?/.test(persons.replaceAll(/\s/g, ""))) {
                return +/(\d+)人?/.exec(persons.replaceAll(" ", ""))[1];
              }
              return undefined;
            })();

            const reversable = !/不[^反]*反串/.test(persons);

            const week =
              getRegExpStr(rowList, /周[一二三四五六日]/) ||
              `周${
                ["日", "一", "二", "三", "四", "五", "六"][item.dayjs.day()]
              }`;

            const time = getRegExpStr(rowList, /\d{1,2}[::]\d{2}/);

            const [hour = "", minute = ""] = time.split(/[::]/);

            const duration = getRegExpStr(
              rowList,
              /(?<=(预计时.|时长)\s*[::]\s*).+/
            ).replace(/(h|小时)/, "H");

            const url = `https://yuque.antfin.com/yuhmb7/pksdw8/${item.url}?singleDoc#`;

            return {
              ...item,
              tag,
              level,
              dm,
              week,
              hour,
              minute,
              place,
              persons,
              duration,
              url,
              manCount,
              womanCount,
              personCount,
              reversable,
            };
          });
      })
    );
  }

  async function copyMarkdownInfo(list) {
    const text = `
    # 📢 剧本杀活动通知
    
    ---
    ${list
      .map((item) => {
        return `
    🎬 《${item.name}》${item.tag}${item.level ? `/${item.level}` : ""}
    
    🕙  ${item.month}.${item.date} ${item.week} ${item.hour}:${item.minute} 📍${
          item.place
        }
    
    💎  DM ${item.dm}【${item.persons}·${item.duration}】[报名](${item.url})
    
    ---
    `;
      })
      .join("")}
    
    🔺 入门:新手友好,10推理本以内经验的玩家
          
    🔺 进阶:中等难度,20推理本以内经验的玩家
    
    🔺 烧脑:积极推理、全程在线、20推理本以上
    
    🔍 务必结合自身经验和剧本难度充分评估后报名
      
    🙋‍ [【活动须知】](https://yuque.antfin.com/yuhmb7/pksdw8/hyv3ir5v5gplvvgl?singleDoc#)[【报名规则】](https://yuque.antfin.com/yuhmb7/pksdw8/igri3gwp127v3v32?singleDoc#)[【情感本注意事项】](https://yuque.antfin.com/yuhmb7/pksdw8/sxs3yz5y5b00f65w?singleDoc#)
    
    `;

    exeCommandCopyText(text);
    window.layui?.layer?.msg("已复制到剪贴板");
  }

  async function getCommentsList(list) {
    return Promise.all(
      list.map((item) => {
        return fetch(
          `https://yuque.antfin-inc.com/api/comments/floor?commentable_type=Doc&commentable_id=${item.id}&include_section=true&include_to_user=true&include_reactions=true`,
          {
            headers: {
              accept: "application/json",
              "accept-language": "zh-CN,zh;q=0.9",
              "content-type": "application/json",
              "sec-ch-ua":
                '"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"',
              "sec-ch-ua-mobile": "?0",
              "sec-ch-ua-platform": '"macOS"',
              "sec-fetch-dest": "empty",
              "sec-fetch-mode": "cors",
              "sec-fetch-site": "same-origin",
              "x-csrf-token": "7g3LVrMMDcljwFdl3GBLLIRy",
              "x-requested-with": "XMLHttpRequest",
            },
            referrerPolicy: "strict-origin-when-cross-origin",
            body: null,
            method: "GET",
            mode: "cors",
            credentials: "include",
          }
        )
          .then((res) => res.json())
          .then((res) => {
            return {
              ...item,
              comments: res.data.comments,
            };
          });
      })
    );
  }

  function openActivityModal(list) {
    requestAnimationFrame(() => {
      document
        .querySelector("#murder-activity-btn")
        ?.addEventListener("click", () => {
          const fullList = list.filter((item) => item.isFull);
          const unFullList = list.filter((item) => !item.isFull);
          if (fullList.length === list.length) {
            window.layui?.layer?.msg("所有活动已满人,无需生成 Markdown");
            return;
          }
          const text = `
    # 📢 剧本杀活动通知
        
    ---
    ${unFullList
      .map((item) => {
        return `
    🎬 《${item.name}》${item.tag}${item.level ? `/${item.level}` : ""}
        
    🕙  ${item.month}.${item.date} ${item.week} ${item.hour}:${item.minute} 📍${
          item.place
        }
        
    💎  DM ${item.dm}【${item.persons}·${item.inputValue ?? ""}·${
          item.duration
        }】[报名](${item.url})
    
    ---
    
    `;
      })
      .join("")}
    
    ${
      fullList.length
        ? `
    📎  本周其他剧本活动信息
    ${list
      .filter((item) => item.isFull)
      .map((item) => {
        return `
    ${item.month}月${item.date}日《${item.name}》【满】
    `;
      })
      .join("")}
    ---
    `
        : ""
    }
    
    🔺 入门:新手友好,10推理本以内经验的玩家
          
    🔺 进阶:中等难度,20推理本以内经验的玩家
            
    🔺 烧脑:积极推理、全程在线、20推理本以上
            
    🔍 务必结合自身经验和剧本难度充分评估后报名
              
    🙋‍ [【活动须知】](https://yuque.antfin.com/yuhmb7/pksdw8/hyv3ir5v5gplvvgl?singleDoc#)[【报名规则】](https://yuque.antfin.com/yuhmb7/pksdw8/igri3gwp127v3v32?singleDoc#)[【情感本注意事项】](https://yuque.antfin.com/yuhmb7/pksdw8/sxs3yz5y5b00f65w?singleDoc#)
        
    `;

          exeCommandCopyText(text);
          window.layui?.layer?.msg("已复制到剪贴板");
        });
    });
    layui.layer.open(
      {
        type: 1, // page 层类型
        area: ["800px", "500px"],
        title: "活动报名情况",
        shade: 0.6, // 遮罩透明度
        shadeClose: true, // 点击遮罩区域,关闭弹层
        maxmin: true, // 允许全屏最小化
        anim: 0, // 0-6 的动画形式,-1 不开启
        content: `
                    <div style="padding: 12px; height: 400px; overflow: auto;">
                      ${list
                        .map((item) => {
                          let manCount = 0;
                          let womanCount = 0;
                          let unknownCount = 0;

                          item.comments.forEach((comment) => {
                            const content = chineseToArabic(
                              getInnerText(comment.body) ?? ""
                            );

                            comment.checked = true;
                            if (/[=等]/.test(content)) {
                              comment.checked = false;
                            } else if (
                              /(\d+)\s*男\s*(\d+)\s*女/.test(content)
                            ) {
                              const result = /(\d+)\s*男\s*(\d+)\s*女/.exec(
                                content
                              );
                              manCount += +result[1];
                              womanCount += +result[2];
                              console.log(result);
                            } else if (/(\d+)\s?男/.test(content)) {
                              manCount += +/(\d+)\s?男/.exec(content)[1];
                            } else if (/男[\s+]*(\d+)/.test(content)) {
                              manCount += +/男[\s+]*(\d+)/.exec(content)[1];
                            } else if (/^\+?男$/.test(content)) {
                              manCount += 1;
                            } else if (/(\d+)\s?女/.test(content)) {
                              womanCount += +/(\d+)\s?女/.exec(content)[1];
                            } else if (/女[\s+]*(\d+)/.test(content)) {
                              womanCount += +/女[\s+]*(\d+)/.exec(content)[1];
                            } else if (/^\+?女$/.test(content)) {
                              womanCount += 1;
                            } else if (/\+(\d+)/.test(content)) {
                              unknownCount += +/\+(\d+)/.exec(content)[1];
                            } else if (content === "+") {
                              unknownCount += 1;
                            } else if (/\d+/.test(content)) {
                              unknownCount += +/\d+/.exec(content)[0];
                            } else {
                              comment.checked = false;
                            }
                          });

                          const listHTML = item.comments
                            .map((comment) => {
                              const content = getInnerText(comment.body);
                              return `<a class="${USER_ITEM_CLASS_NAME} ${
                                !comment.checked ? "unchecked" : ""
                              }" href="https://yuque.antfin-inc.com/${
                                comment.user.login
                              }" target="_blank">
                            <img src="${comment.user.avatar_url}"/>
                            <div>
                              <div>${comment.user.name}</div>
                              <div style="font-size: 12px; color: gray; margin-top: 4px;">${content}</div>
                            </div>
                          </a>`;
                            })
                            .join("");

                          const personCount =
                            manCount + womanCount + unknownCount;
                          const status = (() => {
                            if (
                              item.manCount &&
                              item.womanCount &&
                              !item.reversable
                            ) {
                              if (
                                manCount >= item.manCount &&
                                womanCount >= item.womanCount
                              ) {
                                return `<span class="layui-badge layui-bg-green">已满人</span>`;
                              }
                              if (
                                personCount >=
                                item.manCount + item.womanCount
                              ) {
                                return `<span class="layui-badge layui-bg-orange">满人,但男女未满</span>`;
                              }
                              return `<span class="layui-badge layui-bg-red">未满人</span>`;
                            }
                            if (item.personCount) {
                              if (personCount >= item.personCount) {
                                return `<span class="layui-badge layui-bg-green">已满人</span>`;
                              }
                              return `<span class="layui-badge layui-bg-red">未满人</span>`;
                            }
                            return "";
                          })();

                          item.isFull = status.indexOf("已满人") > -1;
                          item.inputValue = (() => {
                            if (
                              item.personCount &&
                              personCount < item.personCount
                            ) {
                              return `=${item.personCount - personCount}`;
                            }
                            if (
                              item.manCount &&
                              item.womanCount &&
                              !item.reversable
                            ) {
                              let result = "=";
                              if (manCount < item.manCount) {
                                result += `${item.manCount - manCount}男`;
                              }
                              if (womanCount < item.womanCount) {
                                result += `${item.womanCount - womanCount}女`;
                              }
                              if (result.length > 1) {
                                return result;
                              }
                            }
                            return "";
                          })();

                          const operation = document.createElement("div");
                          operation.style.width = "120px";
                          const operationId = `murder-operation-${item.uuid}`;
                          operation.id = operationId;

                          operation.style =
                            "display: flex; align-items: center;text-wrap: nowrap;";

                          const updateOperation = () => {
                            const checkboxId = `murder-checkbox-${item.uuid}`;
                            const inputId = `murder-input-${item.uuid}`;
                            let innerHTML = "";
                            if (!item.isFull) {
                              innerHTML += `<input value="${item.inputValue}" type="text" id="${inputId}" class="layui-input" style="margin-right: 6px; width: 80px;" />`;
                            }
                            innerHTML += `<input type="checkbox" id="${checkboxId}" ${
                              item.isFull ? "checked" : ""
                            } /> 满人`;
                            const target =
                              document.querySelector(`#${operationId}`) ??
                              operation;
                            target.innerHTML = innerHTML;
                            requestAnimationFrame(() => {
                              document
                                .querySelector(`#${checkboxId}`)
                                ?.addEventListener(
                                  "change",
                                  (e) => {
                                    item.isFull = !!e.target.checked;
                                    updateOperation();
                                  },
                                  {
                                    once: true,
                                  }
                                );

                              document
                                .querySelector(`#${inputId}`)
                                ?.addEventListener("change", (e) => {
                                  item.inputValue = e.target.value;
                                  console.log("chagne", item.inputValue);
                                });
                            });
                          };

                          updateOperation();

                          return `
                          <div class="layui-card">
                            <div class="layui-card-header" style="display: flex; justify-content: space-between;">
                              <a href="${item.url}" target="_blank">🔗 ${
                            item.title
                          }</a>
                            </div>
                            <div class="layui-card-body">
                              <div class="${USER_LIST_CLASS_NAME}">
                                ${listHTML}
                              </div>
                              <div class="layui-card-footer">
                                <span>要求:${item.persons}</span>
                                <span>当前:${manCount}男${womanCount}女${
                            unknownCount ? `${unknownCount}未知` : ""
                          },共${manCount + womanCount + unknownCount}人</span>
                                ${operation.outerHTML}
                              </div>
                            </div>
                          </div>
                        `;
                        })
                        .join("")}
                    </div>
                    <div style="padding: 4px 12px; position: absolute; width: 100%; bottom: 0; left: 0; text-align: right;">
                        <button type="button" class="layui-btn" id="murder-activity-btn">生成 Markdown</button>
                    </div>
                  `,
      },
      2000
    );
  }

  function openDatePickerModal([start, end]) {
    const modalIndex = layui.layer.open(
      {
        type: 1, // page 层类型
        title: "请选择日期范围",
        shade: 0.6, // 遮罩透明度
        area: ["655px", "400px"],
        shadeClose: true, // 点击遮罩区域,关闭弹层
        maxmin: true, // 允许全屏最小化
        anim: 0, // 0-6 的动画形式,-1 不开启
        content: `
                      <div style="padding: 12px">
                          <div id="date"></div>
                      </div>
                  `,
      },
      2000
    );
    layui.laydate.render({
      elem: "#date",
      range: true,
      type: "date",
      rangeLinked: true,
      weekStart: 1,
      show: true,
      theme: "#0271BD",
      position: "static",
      value: `${start.format("YYYY-MM-DD")} - ${end.format("YYYY-MM-DD")}`,
      mark: {
        [dayjs().format("YYYY-MM-DD")]: "今天",
      },
      shortcuts: [
        {
          text: "本周",
          value: [
            new Date(+dayjs().startOf("week")),
            new Date(+dayjs().endOf("week")),
          ],
        },
        {
          text: "上周",
          value: [
            new Date(+dayjs().startOf("week").subtract(1, "week")),
            new Date(+dayjs().endOf("week").subtract(1, "week")),
          ],
        },
        {
          text: "下周",
          value: [
            new Date(+dayjs().startOf("week").add(1, "week")),
            new Date(+dayjs().endOf("week").add(1, "week")),
          ],
        },
        {
          text: "本月",
          value: [
            new Date(+dayjs().startOf("month")),
            new Date(+dayjs().endOf("month")),
          ],
        },
        // 更多选项 …
      ],
      done: function (value, startDate, endDate) {
        const [startStr, endStr] = value.split(" - ");
        timeRange = [
          dayjs(startStr, "YYYY-MM-DD"),
          dayjs(endStr, "YYYY-MM-DD"),
        ];
        layui.dropdown.reload(BTN_ID, {
          data: getDropdownItems(),
        });
        layui.layer.close(modalIndex);
      },
    });
  }

  initStyle();
  initBtn();

  function getDropdownItems() {
    return [
      {
        title: "导出所有参与人员报名结果",
        id: "export all user activity",
      },
      {
        title: `日期范围:${timeRange[0].format("M-D")} - ${timeRange[1].format(
          "M-D"
        )}`,
        disabled: true,
      },
      {
        title: `更改日期范围`,
        id: "edit date range",
      },
      {
        title: "复制活动信息 Markdown",
        id: "copy week markdown",
      },
      {
        title: "查看活动报名情况",
        id: "check sign up",
      },
    ];
  }

  layui.dropdown.render({
    elem: `#${BTN_ID}`,
    data: getDropdownItems(),
    click: async function ({ id }) {
      if (id === "export all user activity") {
        const list = await getCommentsList(await getAllActivesInfo());
        const userMap = new Map();
        list.forEach((item) => {
          item.comments.forEach((comment) => {
            const userName = comment.user.name;
            userMap.set(userName, (userMap.get(userName) ?? 0) + 1);
          });
        });

        const result = Array.from(userMap.entries()).sort(
          (a, b) => b[1] - a[1]
        );
        const csv = `name,count\n${result
          .map((item) => `${item[0]},${item[1]}`)
          .join("\n")}`;

        downloadFile(csv, "result.csv");

        return;
      }
      let list = await getActivesInfo(...timeRange);
      if (id === "edit date range") {
        openDatePickerModal(timeRange);
      }
      if (id === "copy week markdown") {
        copyMarkdownInfo(list);
      }
      if (id === "check sign up") {
        list = await getCommentsList(list);
        openActivityModal(list);
      }
    },
  });
})();