chore: clarify export labels and tooltips

This commit is contained in:
admin123 2026-05-19 16:46:49 +08:00
parent 50933af0a6
commit 303efcdc8f
10 changed files with 63 additions and 32 deletions

View File

@ -107,7 +107,7 @@
]; ];
var RATE_COLUMNS = [ var RATE_COLUMNS = [
{ {
header: "\u5355\u89C6\u9891\u770B\u540E\u641C\u7387", header: "\u5546\u5355\u89C6\u9891\u770B\u540E\u641C\u7387",
readValue: (record) => record.rates?.singleVideoAfterSearchRate ? normalizeRateDisplay(record.rates.singleVideoAfterSearchRate) : "" readValue: (record) => record.rates?.singleVideoAfterSearchRate ? normalizeRateDisplay(record.rates.singleVideoAfterSearchRate) : ""
}, },
{ {
@ -2008,7 +2008,7 @@
} }
const selectionHeader = ensureSyntheticHeaderCell(header, SELECTION_COLUMN_KEY, ""); const selectionHeader = ensureSyntheticHeaderCell(header, SELECTION_COLUMN_KEY, "");
const headerSelectionCheckbox = ensureSelectionHeaderControl(selectionHeader); const headerSelectionCheckbox = ensureSelectionHeaderControl(selectionHeader);
ensureSyntheticHeaderCell(header, SINGLE_COLUMN_KEY, "\u5355\u89C6\u9891\u770B\u540E\u641C\u7387"); ensureSyntheticHeaderCell(header, SINGLE_COLUMN_KEY, "\u5546\u5355\u89C6\u9891\u770B\u540E\u641C\u7387");
ensureSyntheticHeaderCell(header, PERSONAL_COLUMN_KEY, "\u4E2A\u4EBA\u89C6\u9891\u770B\u540E\u641C\u7387"); ensureSyntheticHeaderCell(header, PERSONAL_COLUMN_KEY, "\u4E2A\u4EBA\u89C6\u9891\u770B\u540E\u641C\u7387");
BACKEND_METRIC_COLUMNS2.forEach(({ field, label }) => { BACKEND_METRIC_COLUMNS2.forEach(({ field, label }) => {
ensureSyntheticHeaderCell(header, field, label); ensureSyntheticHeaderCell(header, field, label);
@ -2185,7 +2185,7 @@
pluginHeaderSection, pluginHeaderSection,
headerTemplateCell, headerTemplateCell,
SINGLE_COLUMN_KEY, SINGLE_COLUMN_KEY,
"\u5355\u89C6\u9891\u770B\u540E\u641C\u7387" "\u5546\u5355\u89C6\u9891\u770B\u540E\u641C\u7387"
); );
ensureDivHeaderCell( ensureDivHeaderCell(
pluginHeaderSection, pluginHeaderSection,
@ -2836,7 +2836,7 @@
function shouldExportColumn(label) { function shouldExportColumn(label) {
const excludedBackendLabels = new Set(BACKEND_METRIC_COLUMNS2.map((column) => column.label)); const excludedBackendLabels = new Set(BACKEND_METRIC_COLUMNS2.map((column) => column.label));
return Boolean( return Boolean(
label && label !== ACTION_HEADER_TEXT && label !== BACKEND_HEADER_TEXT && !excludedBackendLabels.has(label) && label !== "\u5355\u89C6\u9891\u770B\u540E\u641C\u7387" && label !== "\u4E2A\u4EBA\u89C6\u9891\u770B\u540E\u641C\u7387" label && label !== ACTION_HEADER_TEXT && label !== BACKEND_HEADER_TEXT && !excludedBackendLabels.has(label) && label !== "\u5546\u5355\u89C6\u9891\u770B\u540E\u641C\u7387" && label !== "\u4E2A\u4EBA\u89C6\u9891\u770B\u540E\u641C\u7387"
); );
} }
function syncSortableHeaderCell(cell, options) { function syncSortableHeaderCell(cell, options) {
@ -3577,23 +3577,28 @@
const exportButton = document2.createElement("button"); const exportButton = document2.createElement("button");
exportButton.type = "button"; exportButton.type = "button";
exportButton.dataset.pluginExport = "button"; exportButton.dataset.pluginExport = "button";
exportButton.textContent = "\u5BFC\u51FACSV"; exportButton.textContent = "\u5BFC\u51FA\u5217\u8868CSV";
exportButton.title = "\u5BFC\u51FA\u5F53\u524D\u8FBE\u4EBA\u5217\u8868\u4E2D\u7684\u57FA\u7840\u5B57\u6BB5\u548C\u79D2\u601D\u6307\u6807";
const audienceProfileExportButton = document2.createElement("button"); const audienceProfileExportButton = document2.createElement("button");
audienceProfileExportButton.type = "button"; audienceProfileExportButton.type = "button";
audienceProfileExportButton.dataset.pluginExportAudienceProfile = "button"; audienceProfileExportButton.dataset.pluginExportAudienceProfile = "button";
audienceProfileExportButton.textContent = "\u5BFC\u51FA\u753B\u50CFCSV"; audienceProfileExportButton.textContent = "\u5BFC\u51FA\u9009\u4E2D\u8FBE\u4EBA\u753B\u50CF";
audienceProfileExportButton.title = "\u4EC5\u5BFC\u51FA\u5DF2\u52FE\u9009\u8FBE\u4EBA\uFF0C\u5305\u542B\u753B\u50CF\u3001\u5185\u5BB9\u6570\u636E\u3001\u6548\u679C\u9884\u4F30\u7B49\u5B57\u6BB5";
const audienceProfileByIdExportButton = document2.createElement("button"); const audienceProfileByIdExportButton = document2.createElement("button");
audienceProfileByIdExportButton.type = "button"; audienceProfileByIdExportButton.type = "button";
audienceProfileByIdExportButton.dataset.pluginExportAudienceProfileById = "button"; audienceProfileByIdExportButton.dataset.pluginExportAudienceProfileById = "button";
audienceProfileByIdExportButton.textContent = "\u6309ID\u5BFC\u51FA\u753B\u50CFCSV"; audienceProfileByIdExportButton.textContent = "\u6309\u661F\u56FEID\u5BFC\u51FA\u753B\u50CF";
audienceProfileByIdExportButton.title = "\u7C98\u8D34\u8FBE\u4EBA\u661F\u56FEID\u540E\u6279\u91CF\u5BFC\u51FA\u753B\u50CF\u6570\u636E\uFF0C\u4E0D\u4F9D\u8D56\u5F53\u524D\u5217\u8868\u52FE\u9009";
const audienceProfileFieldButton = document2.createElement("button"); const audienceProfileFieldButton = document2.createElement("button");
audienceProfileFieldButton.type = "button"; audienceProfileFieldButton.type = "button";
audienceProfileFieldButton.dataset.pluginAudienceProfileFields = "button"; audienceProfileFieldButton.dataset.pluginAudienceProfileFields = "button";
audienceProfileFieldButton.textContent = "\u753B\u50CF\u5B57\u6BB5"; audienceProfileFieldButton.textContent = "\u9009\u62E9\u753B\u50CF\u5B57\u6BB5";
audienceProfileFieldButton.title = "\u52FE\u9009\u672C\u6B21\u753B\u50CFCSV\u9700\u8981\u5BFC\u51FA\u7684\u5B57\u6BB5\uFF0C\u8BBE\u7F6E\u4F1A\u81EA\u52A8\u4FDD\u5B58";
const batchSubmitButton = document2.createElement("button"); const batchSubmitButton = document2.createElement("button");
batchSubmitButton.type = "button"; batchSubmitButton.type = "button";
batchSubmitButton.dataset.pluginBatchSubmit = "button"; batchSubmitButton.dataset.pluginBatchSubmit = "button";
batchSubmitButton.textContent = "\u63D0\u4EA4\u6279\u6B21"; batchSubmitButton.textContent = "\u63D0\u4EA4\u6279\u6B21";
batchSubmitButton.title = "\u5C06\u5F53\u524D\u9009\u4E2D\u7684\u8FBE\u4EBA\u63D0\u4EA4\u5230\u540E\u7EED\u4E1A\u52A1\u6279\u6B21";
const exportStatusText = document2.createElement("span"); const exportStatusText = document2.createElement("span");
exportStatusText.dataset.pluginExportStatus = "text"; exportStatusText.dataset.pluginExportStatus = "text";
applyStatusStyles(exportStatusText); applyStatusStyles(exportStatusText);

View File

@ -191,14 +191,14 @@ https://xingtu.cn/ad/creator/market
在星图页面中,插件会新增一组自己的操作区,常见元素包括: 在星图页面中,插件会新增一组自己的操作区,常见元素包括:
- 导出范围下拉框 - 导出范围下拉框
- `导出CSV` 按钮 - `导出列表CSV` 按钮
- `提交批次` 按钮 - `提交批次` 按钮
- 状态提示文字 - 状态提示文字
- 每一行达人前面的勾选框 - 每一行达人前面的勾选框
其中: 其中:
- `导出CSV`:把当前选择的数据导出为表格文件 - `导出列表CSV`:把当前选择的数据导出为表格文件
- `提交批次`:把当前选择的数据提交为批次 - `提交批次`:把当前选择的数据提交为批次
--- ---
@ -243,7 +243,7 @@ https://xingtu.cn/ad/creator/market
点击: 点击:
- `导出CSV` - `导出列表CSV`
### 4. 等待导出完成 ### 4. 等待导出完成
@ -281,7 +281,7 @@ https://xingtu.cn/ad/creator/market
如果只想导出一部分画像字段,点击: 如果只想导出一部分画像字段,点击:
- `画像字段` - `选择画像字段`
在弹出的窗口里: 在弹出的窗口里:
@ -302,11 +302,11 @@ https://xingtu.cn/ad/creator/market
勾选达人后,点击: 勾选达人后,点击:
- `导出画像CSV` - `导出选中达人画像`
如果已经有达人星图 ID 列表,也可以点击: 如果已经有达人星图 ID 列表,也可以点击:
- `按ID导出画像CSV` - `按星图ID导出画像`
然后把达人 ID 粘贴进去,每行一个。 然后把达人 ID 粘贴进去,每行一个。
@ -518,7 +518,7 @@ https://xingtu.cn/ad/creator/market
4. 打开星图达人市场页 4. 打开星图达人市场页
5. 等待页面数据加载完成 5. 等待页面数据加载完成
6. 先勾选需要的人,或直接选择范围 6. 先勾选需要的人,或直接选择范围
7. 需要表格时点 `导出CSV` 7. 需要表格时点 `导出列表CSV`
8. 需要进入后续流程时点 `提交批次` 8. 需要进入后续流程时点 `提交批次`
--- ---

View File

@ -76,7 +76,7 @@ https://xingtu.cn/ad/creator/market
- 勾选你想导出的达人(不勾就选全部) - 勾选你想导出的达人(不勾就选全部)
- 选择范围:当前页 / 前5页 / 全部 - 选择范围:当前页 / 前5页 / 全部
- 点击 **"导出CSV"** - 点击 **"导出列表CSV"**
- 文件自动下载到电脑的"下载"文件夹 - 文件自动下载到电脑的"下载"文件夹
### 2⃣ 导出画像数据画像CSV ### 2⃣ 导出画像数据画像CSV
@ -85,7 +85,7 @@ https://xingtu.cn/ad/creator/market
- 先勾选你想导出画像的达人 - 先勾选你想导出画像的达人
- 选择范围:当前页 / 前5页 / 全部 - 选择范围:当前页 / 前5页 / 全部
- 点击 **"导出画像CSV"** - 点击 **"导出选中达人画像"**
- 等待下载完成 - 等待下载完成
- 文件自动下载到电脑的"下载"文件夹 - 文件自动下载到电脑的"下载"文件夹
@ -98,10 +98,10 @@ https://xingtu.cn/ad/creator/market
- 秒思api数据看后搜率、看后搜数、新增A3数、新增A3率、CPA3、cp_search - 秒思api数据看后搜率、看后搜数、新增A3数、新增A3率、CPA3、cp_search
**只导出部分字段** **只导出部分字段**
- 点击 **"画像字段"** - 点击 **"选择画像字段"**
- 勾选你需要的字段,取消不需要的字段 - 勾选你需要的字段,取消不需要的字段
- 点击 **"保存"** - 点击 **"保存"**
- 再点击 **"导出画像CSV"** 或 **"按ID导出画像CSV"** - 再点击 **"导出选中达人画像"** 或 **"按星图ID导出画像"**
说明达人ID、达人名称、导出状态、失败原因等基础字段会固定保留你保存过一次后下次导出会自动沿用这次勾选结果不需要重新勾选。 说明达人ID、达人名称、导出状态、失败原因等基础字段会固定保留你保存过一次后下次导出会自动沿用这次勾选结果不需要重新勾选。
@ -109,7 +109,7 @@ https://xingtu.cn/ad/creator/market
当你想批量查询特定达人ID的画像数据时使用 当你想批量查询特定达人ID的画像数据时使用
- 点击 **"按ID导出画像CSV"** - 点击 **"按星图ID导出画像"**
- 在弹出的对话框中输入达人ID每行一个 - 在弹出的对话框中输入达人ID每行一个
- 点击确认 - 点击确认
- 等待下载完成 - 等待下载完成

View File

@ -28,7 +28,7 @@ const FALLBACK_BASE_COLUMNS: CsvColumn[] = [
const RATE_COLUMNS: CsvColumn[] = [ const RATE_COLUMNS: CsvColumn[] = [
{ {
header: "单视频看后搜率", header: "单视频看后搜率",
readValue: (record: MarketRecord) => readValue: (record: MarketRecord) =>
record.rates?.singleVideoAfterSearchRate record.rates?.singleVideoAfterSearchRate
? normalizeRateDisplay(record.rates.singleVideoAfterSearchRate) ? normalizeRateDisplay(record.rates.singleVideoAfterSearchRate)

View File

@ -298,7 +298,7 @@ function syncSyntheticMarketTable(root: ParentNode): MarketTableDom | null {
const selectionHeader = ensureSyntheticHeaderCell(header, SELECTION_COLUMN_KEY, ""); const selectionHeader = ensureSyntheticHeaderCell(header, SELECTION_COLUMN_KEY, "");
const headerSelectionCheckbox = ensureSelectionHeaderControl(selectionHeader); const headerSelectionCheckbox = ensureSelectionHeaderControl(selectionHeader);
ensureSyntheticHeaderCell(header, SINGLE_COLUMN_KEY, "单视频看后搜率"); ensureSyntheticHeaderCell(header, SINGLE_COLUMN_KEY, "单视频看后搜率");
ensureSyntheticHeaderCell(header, PERSONAL_COLUMN_KEY, "个人视频看后搜率"); ensureSyntheticHeaderCell(header, PERSONAL_COLUMN_KEY, "个人视频看后搜率");
BACKEND_METRIC_COLUMNS.forEach(({ field, label }) => { BACKEND_METRIC_COLUMNS.forEach(({ field, label }) => {
ensureSyntheticHeaderCell(header, field, label); ensureSyntheticHeaderCell(header, field, label);
@ -532,7 +532,7 @@ function syncDivGridRoot(root: HTMLElement): MarketTableDom | null {
pluginHeaderSection, pluginHeaderSection,
headerTemplateCell, headerTemplateCell,
SINGLE_COLUMN_KEY, SINGLE_COLUMN_KEY,
"单视频看后搜率" "单视频看后搜率"
); );
ensureDivHeaderCell( ensureDivHeaderCell(
pluginHeaderSection, pluginHeaderSection,
@ -1428,7 +1428,7 @@ function shouldExportColumn(label: string): boolean {
label !== ACTION_HEADER_TEXT && label !== ACTION_HEADER_TEXT &&
label !== BACKEND_HEADER_TEXT && label !== BACKEND_HEADER_TEXT &&
!excludedBackendLabels.has(label) && !excludedBackendLabels.has(label) &&
label !== "单视频看后搜率" && label !== "单视频看后搜率" &&
label !== "个人视频看后搜率" label !== "个人视频看后搜率"
); );
} }

View File

@ -79,27 +79,35 @@ export function ensurePluginToolbar(
const exportButton = document.createElement("button"); const exportButton = document.createElement("button");
exportButton.type = "button"; exportButton.type = "button";
exportButton.dataset.pluginExport = "button"; exportButton.dataset.pluginExport = "button";
exportButton.textContent = "导出CSV"; exportButton.textContent = "导出列表CSV";
exportButton.title = "导出当前达人列表中的基础字段和秒思指标";
const audienceProfileExportButton = document.createElement("button"); const audienceProfileExportButton = document.createElement("button");
audienceProfileExportButton.type = "button"; audienceProfileExportButton.type = "button";
audienceProfileExportButton.dataset.pluginExportAudienceProfile = "button"; audienceProfileExportButton.dataset.pluginExportAudienceProfile = "button";
audienceProfileExportButton.textContent = "导出画像CSV"; audienceProfileExportButton.textContent = "导出选中达人画像";
audienceProfileExportButton.title =
"仅导出已勾选达人,包含画像、内容数据、效果预估等字段";
const audienceProfileByIdExportButton = document.createElement("button"); const audienceProfileByIdExportButton = document.createElement("button");
audienceProfileByIdExportButton.type = "button"; audienceProfileByIdExportButton.type = "button";
audienceProfileByIdExportButton.dataset.pluginExportAudienceProfileById = "button"; audienceProfileByIdExportButton.dataset.pluginExportAudienceProfileById = "button";
audienceProfileByIdExportButton.textContent = "按ID导出画像CSV"; audienceProfileByIdExportButton.textContent = "按星图ID导出画像";
audienceProfileByIdExportButton.title =
"粘贴达人星图ID后批量导出画像数据不依赖当前列表勾选";
const audienceProfileFieldButton = document.createElement("button"); const audienceProfileFieldButton = document.createElement("button");
audienceProfileFieldButton.type = "button"; audienceProfileFieldButton.type = "button";
audienceProfileFieldButton.dataset.pluginAudienceProfileFields = "button"; audienceProfileFieldButton.dataset.pluginAudienceProfileFields = "button";
audienceProfileFieldButton.textContent = "画像字段"; audienceProfileFieldButton.textContent = "选择画像字段";
audienceProfileFieldButton.title =
"勾选本次画像CSV需要导出的字段设置会自动保存";
const batchSubmitButton = document.createElement("button"); const batchSubmitButton = document.createElement("button");
batchSubmitButton.type = "button"; batchSubmitButton.type = "button";
batchSubmitButton.dataset.pluginBatchSubmit = "button"; batchSubmitButton.dataset.pluginBatchSubmit = "button";
batchSubmitButton.textContent = "提交批次"; batchSubmitButton.textContent = "提交批次";
batchSubmitButton.title = "将当前选中的达人提交到后续业务批次";
const exportStatusText = document.createElement("span"); const exportStatusText = document.createElement("span");
exportStatusText.dataset.pluginExportStatus = "text"; exportStatusText.dataset.pluginExportStatus = "text";

View File

@ -14,7 +14,7 @@ describe("csv-exporter", () => {
"达人名称", "达人名称",
"地区", "地区",
"21-60s报价", "21-60s报价",
"单视频看后搜率", "单视频看后搜率",
"个人视频看后搜率", "个人视频看后搜率",
"秒思api-看后搜率", "秒思api-看后搜率",
"秒思api-看后搜数", "秒思api-看后搜数",
@ -59,7 +59,7 @@ describe("csv-exporter", () => {
"达人信息", "达人信息",
"粉丝数", "粉丝数",
"21-60s报价", "21-60s报价",
"单视频看后搜率", "单视频看后搜率",
"个人视频看后搜率", "个人视频看后搜率",
"秒思api-看后搜率", "秒思api-看后搜率",
"秒思api-看后搜数", "秒思api-看后搜数",
@ -94,7 +94,7 @@ describe("csv-exporter", () => {
[ [
"达人信息", "达人信息",
"粉丝数", "粉丝数",
"单视频看后搜率", "单视频看后搜率",
"个人视频看后搜率", "个人视频看后搜率",
"秒思api-看后搜率", "秒思api-看后搜率",
"秒思api-看后搜数", "秒思api-看后搜数",

View File

@ -347,6 +347,24 @@ describe("market-content-entry", () => {
const audienceProfileByIdExportButton = document.querySelector( const audienceProfileByIdExportButton = document.querySelector(
'[data-plugin-export-audience-profile-by-id="button"]' '[data-plugin-export-audience-profile-by-id="button"]'
) as HTMLButtonElement | null; ) as HTMLButtonElement | null;
const audienceProfileFieldButton = document.querySelector(
'[data-plugin-audience-profile-fields="button"]'
) as HTMLButtonElement | null;
expect(exportButton?.textContent).toBe("导出列表CSV");
expect(exportButton?.title).toBe("导出当前达人列表中的基础字段和秒思指标");
expect(audienceProfileExportButton?.textContent).toBe("导出选中达人画像");
expect(audienceProfileExportButton?.title).toBe(
"仅导出已勾选达人,包含画像、内容数据、效果预估等字段"
);
expect(audienceProfileByIdExportButton?.textContent).toBe("按星图ID导出画像");
expect(audienceProfileByIdExportButton?.title).toBe(
"粘贴达人星图ID后批量导出画像数据不依赖当前列表勾选"
);
expect(audienceProfileFieldButton?.textContent).toBe("选择画像字段");
expect(audienceProfileFieldButton?.title).toBe(
"勾选本次画像CSV需要导出的字段设置会自动保存"
);
expect(batchSubmitButton?.title).toBe("将当前选中的达人提交到后续业务批次");
expect(exportButton?.style.backgroundColor).toBe("rgb(127, 29, 45)"); expect(exportButton?.style.backgroundColor).toBe("rgb(127, 29, 45)");
expect(batchSubmitButton?.style.backgroundColor).toBe("rgb(127, 29, 45)"); expect(batchSubmitButton?.style.backgroundColor).toBe("rgb(127, 29, 45)");
expect(audienceProfileExportButton?.style.backgroundColor).toBe("rgb(127, 29, 45)"); expect(audienceProfileExportButton?.style.backgroundColor).toBe("rgb(127, 29, 45)");

View File

@ -181,7 +181,7 @@ describe("market-dom-sync", () => {
expect(readSelectionHeaderText()).toBe("全选"); expect(readSelectionHeaderText()).toBe("全选");
expect(readSelectionRowCheckboxCount()).toBe(2); expect(readSelectionRowCheckboxCount()).toBe(2);
expect(readPluginHeaderTexts()).toEqual([ expect(readPluginHeaderTexts()).toEqual([
"单视频看后搜率", "单视频看后搜率",
"个人视频看后搜率", "个人视频看后搜率",
"看后搜率", "看后搜率",
"看后搜数", "看后搜数",