Sfoglia il codice sorgente

feat(mode_workflow): Query 规则 维度 chips(扁平单选 + 实质/形式 接口下钻)

刘文武 1 settimana fa
parent
commit
4cbecbb5d6
1 ha cambiato i file con 70 aggiunte e 0 eliminazioni
  1. 70 0
      examples/mode_workflow/index.html

+ 70 - 0
examples/mode_workflow/index.html

@@ -2068,6 +2068,12 @@
           transform: translateY(-8px);
         }
       }
+      .qr-row { display:flex; align-items:flex-start; gap:10px; padding:5px 0; border-bottom:1px solid #f4f4f4; }
+      .qr-lab { min-width:64px; color:#999; font-size:12.5px; padding-top:6px; flex-shrink:0; }
+      .qr-chips { display:flex; flex-wrap:wrap; gap:7px; flex:1; }
+      .chip { padding:4px 13px; border-radius:18px; font-size:12.5px; cursor:pointer; border:1.5px solid #e2e2e2; background:#fff; color:#666; }
+      .chip:hover { border-color:#bbb; color:#333; }
+      .chip.on { background:#1a1a1a; border-color:#1a1a1a; color:#fff; }
     </style>
   </head>
   <body>
@@ -3652,6 +3658,70 @@
         matrix: null,                              // /api/query_matrix
         scores: null,                              // 最近一次评分结果 cells
       };
+      function qrChip(label, active, on) {
+        const b = document.createElement("button");
+        b.className = "chip" + (active ? " on" : "");
+        b.textContent = label;
+        b.onclick = on;
+        return b;
+      }
+      function renderQrDims() {
+        const root = $("#qr-dims");
+        root.innerHTML = "";
+        // 扁平维度
+        QR_FLAT.forEach((d) => {
+          const row = document.createElement("div");
+          row.className = "qr-row";
+          row.innerHTML = `<span class="qr-lab">· ${d.label}</span>`;
+          const wrap = document.createElement("span");
+          wrap.className = "qr-chips";
+          wrap.appendChild(qrChip("无", qrState.flat[d.id] == null, () => { qrState.flat[d.id] = null; renderQrDims(); }));
+          d.items.forEach((it) =>
+            wrap.appendChild(qrChip(it, qrState.flat[d.id] === it, () => { qrState.flat[d.id] = it; renderQrDims(); })));
+          row.appendChild(wrap);
+          root.appendChild(row);
+        });
+        // 实质/形式 下钻:每一层一行,展示当前层可选项;选中后再展开下一层
+        QR_TREE.forEach((d) => {
+          const data = qrState.treeData[d.id];
+          const path = qrState.treePath[d.id];
+          // 沿 path 定位到当前层的 children 列表(逐层)
+          let level = data ? data.tree : [];
+          const rows = [];
+          for (let depth = 0; ; depth++) {
+            const labtxt = depth === 0 ? `· ${d.label}` : "";
+            const row = document.createElement("div");
+            row.className = "qr-row";
+            row.innerHTML = `<span class="qr-lab">${labtxt}</span>`;
+            const wrap = document.createElement("span");
+            wrap.className = "qr-chips";
+            wrap.appendChild(qrChip("无", path.length === depth, () => { qrState.treePath[d.id] = path.slice(0, depth); renderQrDims(); }));
+            (level || []).forEach((node) =>
+              wrap.appendChild(qrChip(node.name, path[depth] === node.name,
+                () => { qrState.treePath[d.id] = [...path.slice(0, depth), node.name]; renderQrDims(); })));
+            row.appendChild(wrap);
+            rows.push(row);
+            // 进入已选中节点的下一层
+            const sel = (level || []).find((n) => n.name === path[depth]);
+            if (!sel || !(sel.children && sel.children.length)) break;
+            level = sel.children;
+          }
+          rows.forEach((r) => root.appendChild(r));
+        });
+      }
+      async function qrOpen() {
+        renderQrDims();
+        // 并行拉矩阵 + 两棵分类树(接口挂则该维度降级:提示不可选)
+        try { qrState.matrix = qrState.matrix || await api("/api/query_matrix"); }
+        catch (e) { return toast("内容树矩阵加载失败", "error"); }
+        for (const d of QR_TREE) {
+          if (qrState.treeData[d.id]) continue;
+          try { qrState.treeData[d.id] = await api("/api/category_tree?source_type=" + encodeURIComponent(d.source)); }
+          catch (e) { toast(`${d.label} 接口不可达,该维度暂不可选`, "warn"); }
+        }
+        renderQrDims();
+        renderQrTable();
+      }
 
       /* ════ 新建搜索 ════ */
       /* 渠道下拉多选(选项同 search_eval:小红书/知乎/公众号/抖音/视频号/YouTube) */