feat(pugongying): 将可选字段分为"达人信息"和"粉丝画像"两组

在字段选择下拉列表中添加分组标题,将字段按"达人信息"和"粉丝画像"
两部分展示,搜索过滤时自动隐藏无匹配项的分组标题。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
wxs 2026-03-13 16:28:37 +08:00
parent 572ff95aa9
commit cce8f22e0f

View File

@ -55,6 +55,16 @@
const SELECTABLE_FIELD_PATHS = Object.keys(FIELD_LABEL_MAP).filter( const SELECTABLE_FIELD_PATHS = Object.keys(FIELD_LABEL_MAP).filter(
(path) => !(path in NAMESPACE_LABEL_MAP), (path) => !(path in NAMESPACE_LABEL_MAP),
); );
const FIELD_GROUPS = [
{
label: "达人信息",
fields: SELECTABLE_FIELD_PATHS.filter((p) => !p.startsWith("fansProfile.")),
},
{
label: "粉丝画像",
fields: SELECTABLE_FIELD_PATHS.filter((p) => p.startsWith("fansProfile.")),
},
];
const STORAGE_INPUT_KEY = "xhs-pgy-export:last-input"; const STORAGE_INPUT_KEY = "xhs-pgy-export:last-input";
const SCRIPT_FLAG = "__xhsPgyExportMounted__"; const SCRIPT_FLAG = "__xhsPgyExportMounted__";
@ -896,6 +906,14 @@
padding: 2px; padding: 2px;
} }
.xhs-export-group-header {
font-size: 12px;
font-weight: 800;
color: #7a6152;
padding: 6px 4px 2px;
border-bottom: 1px solid rgba(141, 88, 51, 0.15);
}
.xhs-export-select-item { .xhs-export-select-item {
display: grid; display: grid;
gap: 4px; gap: 4px;
@ -1196,24 +1214,36 @@
const search = wrapper.querySelector(".xhs-export-select-search"); const search = wrapper.querySelector(".xhs-export-select-search");
const list = wrapper.querySelector(".xhs-export-select-list"); const list = wrapper.querySelector(".xhs-export-select-list");
for (const field of fieldOptions) { const fieldByPath = new Map(fieldOptions.map((f) => [f.path, f]));
const labelText = field.label || field.path; for (const group of FIELD_GROUPS) {
const item = root.document.createElement("label"); const groupFields = group.fields.filter((p) => fieldByPath.has(p));
item.className = "xhs-export-select-item"; if (!groupFields.length) continue;
item.dataset.path = field.path; const header = root.document.createElement("div");
item.dataset.label = labelText; header.className = "xhs-export-group-header";
item.innerHTML = ` header.textContent = group.label;
<div class="xhs-export-select-item-row"> header.dataset.group = group.label;
<span class="xhs-export-checkbox"> list.appendChild(header);
<input class="xhs-export-checkbox-input" type="checkbox" value="${escapeXml( for (const path of groupFields) {
field.path, const field = fieldByPath.get(path);
)}" ${selected.has(field.path) ? "checked" : ""}> const labelText = field.label || field.path;
<span class="xhs-export-checkbox-box" aria-hidden="true"></span> const item = root.document.createElement("label");
</span> item.className = "xhs-export-select-item";
<span class="xhs-export-field-name">${escapeXml(labelText)}</span> item.dataset.path = field.path;
</div> item.dataset.label = labelText;
`; item.dataset.group = group.label;
list.appendChild(item); item.innerHTML = `
<div class="xhs-export-select-item-row">
<span class="xhs-export-checkbox">
<input class="xhs-export-checkbox-input" type="checkbox" value="${escapeXml(
field.path,
)}" ${selected.has(field.path) ? "checked" : ""}>
<span class="xhs-export-checkbox-box" aria-hidden="true"></span>
</span>
<span class="xhs-export-field-name">${escapeXml(labelText)}</span>
</div>
`;
list.appendChild(item);
}
} }
const setOpenState = (open) => { const setOpenState = (open) => {
@ -1240,6 +1270,13 @@
const path = String(item.dataset.path || "").toLowerCase(); const path = String(item.dataset.path || "").toLowerCase();
item.hidden = q ? !(label.includes(q) || path.includes(q)) : false; item.hidden = q ? !(label.includes(q) || path.includes(q)) : false;
} }
for (const header of list.querySelectorAll(".xhs-export-group-header")) {
const group = header.dataset.group;
const hasVisible = list.querySelector(
`.xhs-export-select-item[data-group="${group}"]:not([hidden])`,
);
header.hidden = !hasVisible;
}
}); });
} }