【api 测活工具++】纯前端版本+ 模型验证 (v1.3 版本已加入官转验证 去新帖)

可以了,能测出来了 :tieba_013:

求助佬们,我把html放在了github page上,但是国内网络无法访问我的Cloudflare Worker导致用不了,怎么解决啊。我是小白,不太懂

现在ok了 :rofl:

@bingloo @yuhuantin @paakjyu 去除live2d 应该是 是live2d 报错,新代码去除了 @Timothy-Yan 自定义域名或者直接用我的

1 个赞

是部署的page 本地上传文件夹 不是work

更新后可以了~

2 个赞

可以用worker搭的,page懒得弄,要建个仓库

1 个赞

key测试工具

1 个赞

page 可以选择上传本地文件,当然现在也有仓库了:GitHub - QAbot-zh/query-key

1 个赞

感谢你的分享!

有趣的玩意
所以我們到底發了甚麼過去

讲一个10个字的故事

2 个赞

Ss的十字故事

好好好!!!

2 个赞

佬能不能搞个http版本,有些站只能ip访问就不行

奥,才看到有源码

1 个赞

我给加上了 抛砖引玉,一个识别中转模型造假的思路 带温度测试的方法,要是可以的话我提交pr了

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>API 信息测活</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="icon"
      href="https://openai.com/favicon.ico"
      type="image/x-icon"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/layui/2.6.8/css/layui.min.css"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/layui/2.6.8/layui.min.js"></script>

    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 40px;
      }

      .container {
        width: 100%;
        max-width: 600px;
        margin: auto;
        padding: 20px;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
      }

      .response-container {
        width: 100%;
        margin: 20px auto 0;
        max-width: 1000px;
        padding: 20px;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        font-size: 16px;
      }

      input[type="text"],
      textarea {
        width: 100%;
        padding: 10px;
        margin: 10px 0;
        box-sizing: border-box;
      }

      textarea {
        height: 100px;
      }

      .submit-container {
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;
      }

      .submit-container input[type="button"],
      .copy-btn {
        width: 30%;
        padding: 10px;
        border: none;
        cursor: pointer;
        margin-top: 10px;
      }

      .copy-btn {
        margin-left: 10%;
        width: 20%;
      }

      .copy-btn2 {
        width: 20%;
      }

      .submit-query {
        background-color: #007bff;
        color: white;
      }

      .check-quota {
        background-color: #28a745;
        color: white;
      }

      .clear-form {
        background-color: #dc3545;
        color: white;
      }

      .model-input-container {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 10px;
      }

      .model-input-container input[type="text"] {
        width: 70%;
        margin-right: 10px;
      }

      .model-input-container input[type="button"] {
        width: 28%;
        background-color: #fe9307;
        color: white;
        border: none;
        cursor: pointer;
      }

      h1 {
        font-weight: bold;
        margin-bottom: 20px;
      }

      h2,
      h3 {
        margin-top: 20px;
        text-align: center;
      }

      .error {
        color: red;
        margin-bottom: 20px;
      }

      .response-container pre {
        white-space: pre-wrap;
        border: 1px solid #ddd;
        padding: 10px;
        background-color: #f9f9f9;
        margin-bottom: 20px;
      }

      .model-timeout-concurrency {
        display: flex;
        justify-content: space-between;
        margin-top: 10px;
      }

      .model-timeout,
      .model-concurrency {
        width: 48%;
      }

      .model-timeout input,
      .model-concurrency input {
        width: 100%;
      }

      table {
        width: 90%; /* 或任何其他固定宽度 */
        margin-left: auto;
        margin-right: auto;
        border-collapse: collapse;
        margin-top: 20px;
      }

      th,
      td {
        border: 1px solid #ddd;
        padding: 8px;
        text-align: left;
      }

      th {
        background-color: #f2f2f2;
      }

      h1,
      h2 {
        color: #007bff;
        text-align: center;
      }

      .td1 {
        width: 250px;
      }

      .td1-ok {
        color: green;
      }

      .td1-no {
        color: coral;
      }

      .td2 {
        width: 200px;
      }

      .td4 {
        max-width: 350px;
        max-height: 100px;
      }

      /* 可以根据需要为 td3 添加样式 */
      .td3 {
        width: 100px; /* 或者设置一个具体的宽度 */
      }

      .copy-buttons {
        margin: 10px 0;
      }

      .copyright {
        margin-top: 20px;
        text-align: center;
        font-size: 14px;
        color: #666;
      }

      .copyright img {
        width: 24px;
        height: 24px;
        border-radius: 50%;
        margin-right: 5px;
        vertical-align: middle;
      }

      .copyright a {
        color: #1e88e5;
        text-decoration: none;
      }

      .copyright a:hover {
        text-decoration: underline;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>API 信息测活</h1>
      <h3>(适配 oneapi/newapi 等中转格式)</h3>

      <form id="apiForm">
        <textarea
          id="api_info"
          name="api_info"
          placeholder="懒人专用文本框,支持同时粘贴接口地址和密钥,智能提取,如:https://api.openai.com,sk-TodayIsThursdayVme50ForKFC"
        ></textarea>
        <input
          type="text"
          id="api_url"
          name="api_url"
          placeholder="接口地址,如:https://api.openai.com"
          value=""
        />
        <input
          type="text"
          id="api_key"
          name="api_key"
          placeholder="密钥,如:sk-TodayIsThursdayVme50ForKFC"
          value=""
        />
        <div class="model-input-container" id="model-input-container">
          <input
            type="text"
            id="model_name"
            name="model_name"
            placeholder="支持手动模型名称,用逗号分隔多个模型"
          />
          <input
            type="button"
            value="获取模型列表"
            style="height: 50px"
            onclick="getModelList()"
          />
        </div>
        <div id="modelCheckboxes"></div>
        <div class="model-timeout-concurrency">
          <div class="model-timeout">
            <label for="model_timeout">设置请求超时(秒):</label>
            <input
              type="number"
              style="height: 30px; width: 70px"
              id="model_timeout"
              name="model_timeout"
              value="10"
              min="1"
            />
          </div>
          <div class="model-concurrency" style="height: 50px">
            <label for="model_concurrency">设置请求并发数量:</label>
            <input
              type="number"
              style="height: 30px; width: 70px"
              id="model_concurrency"
              name="model_concurrency"
              value="5"
              min="1"
            />
          </div>
        </div>
        <div class="submit-container">
          <input
            type="button"
            value="测试模型"
            onclick="testModels()"
            class="submit-query"
          />
          <input
            type="button"
            value="检查额度"
            onclick="checkQuota()"
            class="check-quota"
          />
          <input
            type="button"
            value="清空表单"
            onclick="clearForm()"
            class="clear-form"
          />
        </div>
      </form>
    </div>
    <div class="copyright">
      <!--    不要删除感谢 Rick 和 Megasoft 的贡献-->
      <p>
        © 2024 linuxdo 版权所有<br />贡献者:<a
          href="https://linux.do/u/rick"
          target="_blank"
          ><img
            src="https://linux.do/user_avatar/linux.do/rick/288/137821_2.png"
            alt="rick"
          />rick </a
        >和<a href="https://linux.do/u/zhong_little" target="_blank"
          ><img
            src="https://linux.do/user_avatar/linux.do/zhong_little/288/104887_2.png"
            alt="Megasoft"
          />Megasoft</a
        >
      </p>
    </div>
    <div id="results" class="response-container"></div>

    <script>
      // 智能提取API信息
      document
        .getElementById("api_info")
        .addEventListener("input", function () {
          let text = this.value;
          let urlPattern = /(https?:\/\/[^\s,。、!,;;\n]+)/;
          let keyPattern = /(sk-[a-zA-Z0-9]+)/;

          let urlMatch = text.match(urlPattern);
          let keyMatch = text.match(keyPattern);

          if (urlMatch) {
            //去除末尾/后的空格 其他字符 保留到最后一个/前面
            let cleanUrl = urlMatch[0].match(/(.*)\/.*/)[1];
            //如果. 存在则使用
            if (cleanUrl.includes(".")) {
              document.getElementById("api_url").value = cleanUrl;
              console.log(cleanUrl);
            } else {
              document.getElementById("api_url").value = urlMatch[0];
              console.log(urlMatch[0]);
            }
          }
          if (keyMatch) {
            document.getElementById("api_key").value = keyMatch[0];
          }
        });

      function getModelList() {
        const apiUrl = document.getElementById("api_url").value;
        const apiKey = document.getElementById("api_key").value;
        console.log(apiUrl, apiKey);

        layui.use("layer", function () {
          var layer = layui.layer;

          layer.load();
          fetch(`${apiUrl}/v1/models`, {
            headers: {
              Authorization: `Bearer ${apiKey}`,
              "Content-Type": "application/json",
            },
          })
            .then((response) => response.json())
            .then((data) => {
              layer.closeAll("loading");
              const models = data.data.map((model) => model.id);
              models.sort();
              displayModelCheckboxes(models);
            })
            .catch((error) => {
              layer.closeAll("loading");
              layer.alert("获取模型列表失败: " + error.message);
            });
        });
      }

      // 显示模型复选框
      function displayModelCheckboxes(models) {
        layui.use(["layer", "form"], function () {
          var layer = layui.layer;
          var form = layui.form;

          let content = '<div style="padding: 20px;"><form class="layui-form">';
          content += '<div id="selectedCount">已选择 0 个模型</div>';

          content += `
                    <div class="layui-form-item">
                        <input type="checkbox" lay-skin="primary" lay-filter="checkAll" title="全选">
                    </div>
                `;

          models.forEach((model, index) => {
            content += `
                        <div class="layui-form-item">
                            <input type="checkbox" name="models[${index}]" value="${model}" title="${model}" lay-skin="primary">
                        </div>
                    `;
          });
          content += "</form></div>";

          layer.open({
            type: 1,
            title: "选择模型",
            content: content,
            area: ["300px", "400px"],
            btn: ["确定", "取消"],
            success: function (layero, index) {
              form.render("checkbox");
              form.on("checkbox", function (data) {
                updateSelectedCount(layero);
              });
              form.on("checkbox(checkAll)", function (data) {
                var child = layero
                  .find('input[type="checkbox"]')
                  .not(data.elem);
                child.each(function (index, item) {
                  item.checked = data.elem.checked;
                });
                form.render("checkbox");
                updateSelectedCount(layero);
              });
            },
            yes: function (index, layero) {
              const selectedModels = layero
                .find('input[name^="models"]:checked')
                .map(function () {
                  return this.value;
                })
                .get();
              document.getElementById("model_name").value =
                selectedModels.join(",");
              layer.close(index);
            },
          });
        });
      }

      // 更新已选择的模型数量
      function updateSelectedCount(layero) {
        const selectedCount = layero.find(
          'input[name^="models"]:checked'
        ).length;
        layero.find("#selectedCount").text(`已选择 ${selectedCount} 个模型`);
      }

      let results = {
        valid: [],
        invalid: [],
        inconsistent: [],
      };

      async function testModels() {
        results = {
          valid: [],
          invalid: [],
          inconsistent: [],
        };
        const apiUrl = document.getElementById("api_url").value;
        const apiKey = document.getElementById("api_key").value;
        const modelNames = document
          .getElementById("model_name")
          .value.split(",")
          .map((m) => m.trim())
          .filter((m) => m);
        const timeout =
          parseInt(document.getElementById("model_timeout").value) * 1000; // 转换为毫秒
        const concurrency = parseInt(
          document.getElementById("model_concurrency").value
        );

        if (modelNames.length === 0) {
          layui.use("layer", function () {
            var layer = layui.layer;

            layer.alert("请输入至少一个模型名称或从列表中选择模型");
          });
          return;
        }

        layui.use("layer", function () {
          var layer = layui.layer;
          layer.load();

          // async function testModel(model) {
          //     const controller = new AbortController();
          //     const id = setTimeout(() => controller.abort(), timeout);
          //     const startTime = Date.now();

          //     var response_text;
          //     try {
          //         const response = await fetch(`${apiUrl}/v1/chat/completions`, {
          //             method: 'POST',
          //             headers: {
          //                 'Authorization': `Bearer ${apiKey}`,
          //                 'Content-Type': 'application/json'
          //             },
          //             body: JSON.stringify({
          //                 model: model,
          //                 messages: [{role: "user", content: "Say this is a test!"}]
          //             }),
          //             signal: controller.signal
          //         });

          //         const endTime = Date.now();
          //         const responseTime = (endTime - startTime) / 1000; // 转换为秒

          //         if (response.ok) {
          //             const data = await response.json();
          //             const returnedModel = data.model;
          //             if (returnedModel === model) {
          //                 results.valid.push({model, responseTime});
          //                 console.log(`测试 API 节点:${apiUrl} 测试模型:${model} 模型一致,响应时间:${responseTime.toFixed(2)} 秒`);
          //             } else {
          //                 results.inconsistent.push({model, returnedModel, responseTime});
          //                 console.log(`测试 API 节点:${apiUrl} 测试模型:${model} 模型不一致,期望:${model},实际:${returnedModel},响应时间:${responseTime.toFixed(2)} 秒`);
          //             }
          //         } else {
          //             response_text = await response.text();
          //             results.invalid.push({model, response_text})
          //             console.log(`测试 API 节点:${apiUrl} 测试模型:${model} 模型不可用,响应:${response.status} ${response.statusText} ${response_text}`);
          //         }
          //     } catch (error) {
          //         if (error.name === 'AbortError') {
          //             results.invalid.push({model, error: '超时'});
          //             console.log(`测试 API 节点:${apiUrl} 测试模型:${model} 模型不可用(超时)`);
          //         } else {
          //             results.invalid.push({model, error: error.message});
          //             console.log(`测试 API 节点:${apiUrl} 测试模型:${model} 模型不可用,错误:${error.message}`);
          //         }
          //     } finally {
          //         clearTimeout(id);
          //     }
          // }

          async function testModel(model) {
            const controller = new AbortController();
            const id = setTimeout(() => controller.abort(), timeout);
            const startTime = Date.now();

            var response_text;
            try {
              const responses = await Promise.all(
                Array(4)
                  .fill()
                  .map(() =>
                    fetch(`${apiUrl}/v1/chat/completions`, {
                      method: "POST",
                      headers: {
                        Authorization: `Bearer ${apiKey}`,
                        "Content-Type": "application/json",
                      },
                      body: JSON.stringify({
                        model: model,
                        messages: [
                          {
                            role: "system",
                            content:
                              "You're an associative thinker. The user gives you a sequence of 6 numbers. Your task is to figure out and provide the 7th number directly, without explaining how you got there.",
                          },
                          {
                            role: "user",
                            content: "5, 15, 77, 19, 53, 54,",
                          },
                        ],
                        temperature: 0.01,
                      }),
                      signal: controller.signal,
                    }).then((res) => res.json())
                  )
              );

              const endTime = Date.now();
              const responseTime = (endTime - startTime) / 1000; // 转换为秒

              const allResults = responses.map((data) =>
                data.choices[0].message.content.trim()
              );
              const allSame = allResults.every(
                (result) => result === allResults[0]
              );

              if (allSame) {
                results.valid.push({
                  model,
                  responseTime,
                  result: allResults[0],
                });
                console.log(
                  `测试 API 节点:${apiUrl} 测试模型:${model} 模型一致,响应时间:${responseTime.toFixed(
                    2
                  )} 秒,所有结果都为${allResults[0]}`
                );
              } else {
                results.inconsistent.push({
                  model,
                  responseTime,
                  results: allResults,
                });
                console.log(
                  `测试 API 节点:${apiUrl} 测试模型:${model} 结果不一致,响应时间:${responseTime.toFixed(
                    2
                  )} 秒,结果:${allResults.join(", ")}`
                );
              }
            } catch (error) {
              if (error.name === "AbortError") {
                results.invalid.push({ model, error: "超时" });
                console.log(
                  `测试 API 节点:${apiUrl} 测试模型:${model} 模型不可用(超时)`
                );
              } else {
                results.invalid.push({ model, error: error.message });
                console.log(
                  `测试 API 节点:${apiUrl} 测试模型:${model} 模型不可用,错误:${error.message}`
                );
              }
            } finally {
              clearTimeout(id);
            }
          }

          async function runBatch(models) {
            const promises = models.map((model) => testModel(model));
            await Promise.all(promises);
          }

          async function runAllTests() {
            for (let i = 0; i < modelNames.length; i += concurrency) {
              const batch = modelNames.slice(i, i + concurrency);
              await runBatch(batch);
            }

            layer.closeAll("loading");
            displayResults(results);
            showSummary(results);
          }

          runAllTests().catch((error) => {
            layer.closeAll("loading");
            layer.alert("测试模型时发生错误: " + error.message);
          });
        });
      }

      function showSummary(results) {
        const validCount = results.valid.length;
        const inconsistentCount = results.inconsistent.length;
        const invalidCount = results.invalid.length;
        const totalCount = validCount + inconsistentCount + invalidCount;

        layui.use("layer", function () {
          var layer = layui.layer;
          layer.alert(
            `测试总结:<br>
                    总共测试了 ${totalCount} 个模型<br>
                    其中:<br>
                    - ${validCount} 个模型可用且一致<br>
                    - ${inconsistentCount} 个模型可用但不一致<br>
                    - ${invalidCount} 个模型不可用`,
            { title: "测试结果总结" }
          );
        });
      }

      // 显示测试结果
      // 显示测试结果
      //   function displayResults(results) {
      //     var resultsDiv = document.getElementById("results");
      //     var content =
      //       "<h2>测试结果</h2>" +
      //       '<div class="copy-buttons">' +
      //       '<div className="submit-container">' +
      //       '<button class="check-quota copy-btn" onclick="copyConsistentModels()">复制一致模型</button>' +
      //       '<button class="check-quota copy-btn" onclick="copyConsistentAndInconsistentModels()">复制可用模型</button>' +
      //       '<button class="check-quota copy-btn"onclick="copyConsistentAndInconsistentReturedModels()">复制可用用原始模型</button>' +
      //       "</div>" +
      //       "</div>" +
      //       "<table>" +
      //       "<tr>" +
      //       '<th class="td1">状态</th>' +
      //       '<th class="td2">模型名称</th>' +
      //       '<th class="td3">响应时间 (秒)</th>' +
      //       '<th class="td4">备注</th>' +
      //       "</tr>";

      //     results.valid.forEach(function (r) {
      //       content +=
      //         "<tr>" +
      //         '<td class="td1 td1-ok">模型一致可用</td>' +
      //         '<td class="td2"><span class="copy-btn2"" onclick="copyText(\'' +
      //         r.model +
      //         "')\">" +
      //         r.model +
      //         "</span></td>" +
      //         '<td class="td3">' +
      //         r.responseTime.toFixed(2) +
      //         "</td>" +
      //         '<td class="td4">good</td>' +
      //         "</tr>";
      //     });

      //     results.inconsistent.forEach(function (r) {
      //       content +=
      //         "<tr>" +
      //         '<td class="td1 td1-no" >模型不一致,tnnd掺假?</td>' +
      //         '<td class="td2"><span class="copy-btn2"" onclick="copyText(\'' +
      //         r.model +
      //         "')\">" +
      //         r.model +
      //         "</span></td>" +
      //         '<td class="td3">' +
      //         r.responseTime.toFixed(2) +
      //         "</td>" +
      //         '<td class="td4">返回模型: ' +
      //         r.returnedModel +
      //         "</td>" +
      //         "</tr>";
      //     });

      //     results.invalid.forEach(function (r) {
      //       content +=
      //         "<tr>" +
      //         '<td class="td1 ">模型不可用,干啥呢</td>' +
      //         '<td class="td2"><span class="copy-btn2" onclick="copyText(\'' +
      //         r.model +
      //         "')\">" +
      //         r.model +
      //         "</span></td>" +
      //         '<td class="td3">-</td>' +
      //         '<td class="td4">' +
      //         (r.response_text || r.error) +
      //         "</td>" +
      //         "</tr>";
      //     });

      //     content += "</table>";
      //     resultsDiv.innerHTML = content;
      //   }

      function displayResults(results) {
        var resultsDiv = document.getElementById("results");
        var content =
          "<h2>测试结果</h2>" +
          "<p>参考值:c3.5 = 51(gcp测试),gpt-4o = 59,gpt-4o-mini = 32(azure测试)</p>" +
          '<div class="copy-buttons">' +
          '<div className="submit-container">' +
          '<button class="check-quota copy-btn" onclick="copyConsistentModels()">复制一致模型</button>' +
          '<button class="check-quota copy-btn" onclick="copyConsistentAndInconsistentModels()">复制可用模型</button>' +
          '<button class="check-quota copy-btn"onclick="copyConsistentAndInconsistentReturedModels()">复制可用用原始模型</button>' +
          "</div>" +
          "</div>" +
          "<table>" +
          "<tr>" +
          '<th class="td1">状态</th>' +
          '<th class="td2">模型名称</th>' +
          '<th class="td3">响应时间 (秒)</th>' +
          '<th class="td4">结果</th>' +
          "</tr>";

        results.valid.forEach(function (r) {
          content +=
            "<tr>" +
            '<td class="td1 td1-ok">模型一致可用</td>' +
            '<td class="td2"><span class="copy-btn2"" onclick="copyText(\'' +
            r.model +
            "')\">" +
            r.model +
            "</span></td>" +
            '<td class="td3">' +
            r.responseTime.toFixed(2) +
            "</td>" +
            '<td class="td4">所有结果都为: ' +
            r.result +
            "</td>" +
            "</tr>";
        });

        results.inconsistent.forEach(function (r) {
          content +=
            "<tr>" +
            '<td class="td1 td1-no">结果不一致</td>' +
            '<td class="td2"><span class="copy-btn2"" onclick="copyText(\'' +
            r.model +
            "')\">" +
            r.model +
            "</span></td>" +
            '<td class="td3">' +
            r.responseTime.toFixed(2) +
            "</td>" +
            '<td class="td4">结果: ' +
            r.results.join(", ") +
            "</td>" +
            "</tr>";
        });

        results.invalid.forEach(function (r) {
          content +=
            "<tr>" +
            '<td class="td1">模型不可用</td>' +
            '<td class="td2"><span class="copy-btn2" onclick="copyText(\'' +
            r.model +
            "')\">" +
            r.model +
            "</span></td>" +
            '<td class="td3">-</td>' +
            '<td class="td4">' +
            (r.response_text || r.error) +
            "</td>" +
            "</tr>";
        });

        content += "</table>";
        resultsDiv.innerHTML = content;
      }

      // 复制文本功能
      function copyText(text) {
        navigator.clipboard
          .writeText(text)
          .then(() => {
            layui.use("layer", function () {
              var layer = layui.layer;
              layer.msg("模型名已复制到剪贴板");
            });
          })
          .catch((err) => {
            console.error("复制失败:", err);
          });
      }

      // 检查额度
      function checkQuota() {
        const apiUrl = document.getElementById("api_url").value;
        const apiKey = document.getElementById("api_key").value;

        layui.use("layer", function () {
          var layer = layui.layer;
          layer.load();

          let quotaInfo, usedInfo, remainInfo;

          // 获取总额度
          fetch(`${apiUrl}/dashboard/billing/subscription`, {
            headers: { Authorization: `Bearer ${apiKey}` },
          })
            .then((response) => response.json())
            .then((quotaData) => {
              quotaInfo = quotaData.hard_limit_usd
                ? `${quotaData.hard_limit_usd.toFixed(2)} $`
                : "无法获得额度信息";

              // 获取使用情况
              const today = new Date();
              const year = today.getFullYear();
              const month = String(today.getMonth() + 1).padStart(2, "0");
              const day = String(today.getDate()).padStart(2, "0");
              const startDate = `${year}-${month}-01`;
              const endDate = `${year}-${month}-${day}`;

              return fetch(
                `${apiUrl}/dashboard/billing/usage?start_date=${startDate}&end_date=${endDate}`,
                {
                  headers: { Authorization: `Bearer ${apiKey}` },
                }
              );
            })
            .then((response) => response.json())
            .then((usageData) => {
              usedInfo = `${(usageData.total_usage / 100).toFixed(2)} $`;

              // 计算剩余额度
              const quotaNumber = parseFloat(quotaInfo);
              const usedNumber = parseFloat(usedInfo);
              if (!isNaN(quotaNumber) && !isNaN(usedNumber)) {
                remainInfo = `${(quotaNumber - usedNumber).toFixed(2)} $`;
              } else {
                remainInfo = "无法计算剩余额度";
              }

              const showInfo = `可用额度为: ${remainInfo}\n\n已用额度为: ${usedInfo}\n\n总额度为: ${quotaInfo}`;
              layer.closeAll("loading");
              layer.alert(showInfo);
            })
            .catch((error) => {
              layer.closeAll("loading");
              layer.alert("检查额度失败: " + error.message);
            });
        });
      }

      // 清空表单
      function clearForm() {
        document.getElementById("apiForm").reset();
        document.getElementById("results").innerHTML = "";
      }

      // 复制一致模型
      function copyConsistentModels() {
        var models = results.valid.map(function (r) {
          return r.model;
        });
        copyText(models.join(","));
      }

      // 复制所有可用模型去重
      function copyConsistentAndInconsistentModels() {
        var models = results.valid
          .map(function (r) {
            return r.model;
          })
          .concat(
            results.inconsistent.map(function (r) {
              return r.model;
            })
          );
        var uniqueModels = Array.from(new Set(models)); // 去重
        copyText(uniqueModels.join(","));
      }

      // 复制一致和不一致模型的原始模型的函数名称 去重
      function copyConsistentAndInconsistentReturedModels() {
        var models = results.valid
          .map(function (r) {
            return r.model;
          })
          .concat(
            results.inconsistent.map(function (r) {
              return r.returnedModel;
            })
          );
        var uniqueModels = Array.from(new Set(models)); // 去重
        //去除undefined
        uniqueModels = uniqueModels.filter(function (s) {
          return s && s.trim();
        });
        copyText(uniqueModels.join(","));
      }
    </script>
  </body>
</html>

2 个赞

@zhong_little 准备处理下pr 仓库是他的

emm 有点问题 现在是1.3 你改的好像是1.1,然后我两都是不改原本代码,
原本的测试只测模型名是否一致就不用改了

建议附加一个函数在这里 判断能处理的模型 添加测试按钮,再弹窗展示结果

if (r.model.startsWith('gpt-')) {
                let buttonClass = results.awaitOfficialVerification.some(item => item.model === r.model) ? 'green' : 'yellow';
                verifyButton = '<button class="verify-btn ' + buttonClass + '" onclick="verifyOfficial(\'' + r.model + '\')">官转验证</button>';
            }

逻辑参考

async function verifyOfficial(model) {
        layui.use('layer', function () {
            const layer = layui.layer;
            layer.prompt({
                formType: 0,
                value: '888',
                title: '请输入seed值 (1-900)',
                area: ['300px', '50px']
            }, function (seed, index) {
                layer.close(index);
                performOfficialVerification(model, parseInt(seed));

            });
        });
    }
1 个赞

奥,我复制的是你帖子里的代码

query-key/index.html at main · QAbot-zh/query-key · GitHub 这个·
预览版代码 好像没发 @zhong_little 到时候同步下
一般不该逻辑 添加逻辑就是 方便大家看 我两也没讨论

1 个赞