chore: simplify export action labels

This commit is contained in:
admin123 2026-05-19 17:39:57 +08:00
parent 303efcdc8f
commit 75294ca8c7
10 changed files with 106 additions and 140 deletions

View File

@ -883,7 +883,7 @@
const title = document2.createElement("h2"); const title = document2.createElement("h2");
applyTitleStyles(title); applyTitleStyles(title);
const hint = document2.createElement("p"); const hint = document2.createElement("p");
hint.textContent = "\u57FA\u7840\u5B57\u6BB5\u4F1A\u56FA\u5B9A\u4FDD\u7559\u3002\u53D6\u6D88\u52FE\u9009\u540E\uFF0C\u672C\u6B21\u53CA\u540E\u7EED\u753B\u50CFCSV\u5C06\u4E0D\u5305\u542B\u5BF9\u5E94\u5217\u3002"; hint.textContent = "\u57FA\u7840\u5B57\u6BB5\u4F1A\u56FA\u5B9A\u4FDD\u7559\u3002\u53D6\u6D88\u52FE\u9009\u540E\uFF0C\u672C\u6B21\u53CA\u540E\u7EEDCSV\u5C06\u4E0D\u5305\u542B\u5BF9\u5E94\u5217\u3002";
applyHintStyles(hint); applyHintStyles(hint);
const toolbar = document2.createElement("div"); const toolbar = document2.createElement("div");
applyToolbarStyles(toolbar); applyToolbarStyles(toolbar);
@ -1117,14 +1117,14 @@
const dialog = document2.createElement("section"); const dialog = document2.createElement("section");
applyDialogStyles2(dialog); applyDialogStyles2(dialog);
const title = document2.createElement("h2"); const title = document2.createElement("h2");
title.textContent = "\u6309\u661F\u56FEID\u5BFC\u51FA\u753B\u50CFCSV"; title.textContent = "\u6309\u661F\u56FEID\u5BFC\u51FA";
applyTitleStyles2(title); applyTitleStyles2(title);
const textarea = document2.createElement("textarea"); const textarea = document2.createElement("textarea");
textarea.dataset.authorIdDialogInput = "textarea"; textarea.dataset.authorIdDialogInput = "textarea";
textarea.placeholder = "\u6BCF\u884C\u4E00\u4E2A\u661F\u56FEID\uFF0C\u4E5F\u652F\u6301\u9017\u53F7\u3001\u7A7A\u683C\u5206\u9694"; textarea.placeholder = "\u6BCF\u884C\u4E00\u4E2A\u661F\u56FEID\uFF0C\u4E5F\u652F\u6301\u9017\u53F7\u3001\u7A7A\u683C\u5206\u9694";
applyTextareaStyles(textarea); applyTextareaStyles(textarea);
const hint = document2.createElement("p"); const hint = document2.createElement("p");
hint.textContent = "\u7C98\u8D34\u5BA2\u6237\u63D0\u4F9B\u7684\u8FBE\u4EBA\u661F\u56FEID\uFF0C\u786E\u8BA4\u540E\u5C06\u6279\u91CF\u5BFC\u51FA\u753B\u50CF\u548C\u5546\u4E1A\u80FD\u529B\u6570\u636E\u3002"; hint.textContent = "\u7C98\u8D34\u5BA2\u6237\u63D0\u4F9B\u7684\u8FBE\u4EBA\u661F\u56FEID\uFF0C\u786E\u8BA4\u540E\u5C06\u6279\u91CF\u5BFC\u51FA\u8FBE\u4EBA\u6570\u636E\u3002";
applyHintStyles2(hint); applyHintStyles2(hint);
const actions = document2.createElement("div"); const actions = document2.createElement("div");
applyActionsStyles2(actions); applyActionsStyles2(actions);
@ -3577,23 +3577,23 @@
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\u51FA\u5217\u8868CSV"; exportButton.hidden = true;
exportButton.title = "\u5BFC\u51FA\u5F53\u524D\u8FBE\u4EBA\u5217\u8868\u4E2D\u7684\u57FA\u7840\u5B57\u6BB5\u548C\u79D2\u601D\u6307\u6807"; exportButton.tabIndex = -1;
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\u9009\u4E2D\u8FBE\u4EBA\u753B\u50CF"; audienceProfileExportButton.textContent = "\u5BFC\u51FA\u9009\u4E2D\u8FBE\u4EBA\u6570\u636E";
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"; audienceProfileExportButton.title = "\u4EC5\u5BFC\u51FA\u5DF2\u52FE\u9009\u8FBE\u4EBA\uFF0C\u5305\u542B\u5185\u5BB9\u6570\u636E\u3001\u6548\u679C\u9884\u4F30\u3001\u753B\u50CF\u7B49\u7EF4\u5EA6";
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 = "\u6309\u661F\u56FEID\u5BFC\u51FA\u753B\u50CF"; audienceProfileByIdExportButton.textContent = "\u6309\u661F\u56FEID\u5BFC\u51FA";
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"; audienceProfileByIdExportButton.title = "\u7C98\u8D34\u8FBE\u4EBA\u661F\u56FEID\u540E\u6279\u91CF\u5BFC\u51FA\u8FBE\u4EBA\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 = "\u9009\u62E9\u753B\u50CF\u5B57\u6BB5"; audienceProfileFieldButton.textContent = "\u9009\u62E9\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"; audienceProfileFieldButton.title = "\u52FE\u9009\u672C\u6B21CSV\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";
@ -3877,14 +3877,12 @@
const primaryButton = findButtonContainingText(document2, "\u53D1\u5E03\u4EFB\u52A1") ?? findButtonContainingText(document2, "+\u53D1\u5E03\u4EFB\u52A1"); const primaryButton = findButtonContainingText(document2, "\u53D1\u5E03\u4EFB\u52A1") ?? findButtonContainingText(document2, "+\u53D1\u5E03\u4EFB\u52A1");
const nativeButton = primaryButton ?? findNativeActionButton(document2, "\u81EA\u5B9A\u4E49\u6307\u6807") ?? findNativeActionButton(document2, "\u5BFC\u51FA"); const nativeButton = primaryButton ?? findNativeActionButton(document2, "\u81EA\u5B9A\u4E49\u6307\u6807") ?? findNativeActionButton(document2, "\u5BFC\u51FA");
if (nativeButton) { if (nativeButton) {
controls.exportButton.className = nativeButton.className;
controls.audienceProfileExportButton.className = nativeButton.className; controls.audienceProfileExportButton.className = nativeButton.className;
controls.audienceProfileByIdExportButton.className = nativeButton.className; controls.audienceProfileByIdExportButton.className = nativeButton.className;
controls.audienceProfileFieldButton.className = nativeButton.className; controls.audienceProfileFieldButton.className = nativeButton.className;
controls.batchSubmitButton.className = nativeButton.className; controls.batchSubmitButton.className = nativeButton.className;
} }
[ [
controls.exportButton,
controls.audienceProfileExportButton, controls.audienceProfileExportButton,
controls.audienceProfileByIdExportButton, controls.audienceProfileByIdExportButton,
controls.audienceProfileFieldButton, controls.audienceProfileFieldButton,
@ -3930,7 +3928,6 @@
const style = document2.createElement("style"); const style = document2.createElement("style");
style.id = PLUGIN_ACTION_BUTTON_STYLE_ID; style.id = PLUGIN_ACTION_BUTTON_STYLE_ID;
style.textContent = ` style.textContent = `
[data-plugin-export="button"]:hover:not(:disabled),
[data-plugin-export-audience-profile="button"]:hover:not(:disabled), [data-plugin-export-audience-profile="button"]:hover:not(:disabled),
[data-plugin-export-audience-profile-by-id="button"]:hover:not(:disabled), [data-plugin-export-audience-profile-by-id="button"]:hover:not(:disabled),
[data-plugin-audience-profile-fields="button"]:hover:not(:disabled), [data-plugin-audience-profile-fields="button"]:hover:not(:disabled),
@ -3939,7 +3936,6 @@
border-color: #6d1627 !important; border-color: #6d1627 !important;
} }
[data-plugin-export="button"]:active:not(:disabled),
[data-plugin-export-audience-profile="button"]:active:not(:disabled), [data-plugin-export-audience-profile="button"]:active:not(:disabled),
[data-plugin-export-audience-profile-by-id="button"]:active:not(:disabled), [data-plugin-export-audience-profile-by-id="button"]:active:not(:disabled),
[data-plugin-audience-profile-fields="button"]:active:not(:disabled), [data-plugin-audience-profile-fields="button"]:active:not(:disabled),
@ -3949,7 +3945,6 @@
transform: translateY(1px); transform: translateY(1px);
} }
[data-plugin-export="button"]:focus-visible,
[data-plugin-export-audience-profile="button"]:focus-visible, [data-plugin-export-audience-profile="button"]:focus-visible,
[data-plugin-export-audience-profile-by-id="button"]:focus-visible, [data-plugin-export-audience-profile-by-id="button"]:focus-visible,
[data-plugin-audience-profile-fields="button"]:focus-visible, [data-plugin-audience-profile-fields="button"]:focus-visible,
@ -3958,7 +3953,6 @@
box-shadow: 0 0 0 3px rgba(127, 29, 45, 0.2) !important; box-shadow: 0 0 0 3px rgba(127, 29, 45, 0.2) !important;
} }
[data-plugin-export="button"]:disabled,
[data-plugin-export-audience-profile="button"]:disabled, [data-plugin-export-audience-profile="button"]:disabled,
[data-plugin-export-audience-profile-by-id="button"]:disabled, [data-plugin-export-audience-profile-by-id="button"]:disabled,
[data-plugin-audience-profile-fields="button"]:disabled, [data-plugin-audience-profile-fields="button"]:disabled,
@ -4659,7 +4653,7 @@
onExportAudienceProfile: async () => { onExportAudienceProfile: async () => {
syncSelectionStateFromDom(); syncSelectionStateFromDom();
if (selectedAuthorIds.size === 0) { if (selectedAuthorIds.size === 0) {
setToolbarExportStatus(toolbar, "\u8BF7\u5148\u52FE\u9009\u9700\u8981\u5BFC\u51FA\u753B\u50CF\u7684\u8FBE\u4EBA"); setToolbarExportStatus(toolbar, "\u8BF7\u5148\u52FE\u9009\u9700\u8981\u5BFC\u51FA\u6570\u636E\u7684\u8FBE\u4EBA");
return; return;
} }
const exportTarget = readToolbarExportTarget(toolbar); const exportTarget = readToolbarExportTarget(toolbar);
@ -4778,7 +4772,7 @@
saveAudienceProfileSelectedHeaders(nextHeaders); saveAudienceProfileSelectedHeaders(nextHeaders);
setToolbarExportStatus( setToolbarExportStatus(
toolbar, toolbar,
`\u753B\u50CF\u5B57\u6BB5\u5DF2\u4FDD\u5B58\uFF08\u5DF2\u9009 ${nextHeaders.length}/${readAudienceProfileSelectableHeaders().length} \u4E2A\u5B57\u6BB5\uFF09` `\u5B57\u6BB5\u5DF2\u4FDD\u5B58\uFF08\u5DF2\u9009 ${nextHeaders.length}/${readAudienceProfileSelectableHeaders().length} \u4E2A\u5B57\u6BB5\uFF09`
); );
}, },
onSubmitBatch: async () => { onSubmitBatch: async () => {

View File

@ -191,14 +191,14 @@ https://xingtu.cn/ad/creator/market
在星图页面中,插件会新增一组自己的操作区,常见元素包括: 在星图页面中,插件会新增一组自己的操作区,常见元素包括:
- 导出范围下拉框 - 导出范围下拉框
- `导出列表CSV` 按钮 - `导出选中达人数据` 按钮
- `提交批次` 按钮 - `提交批次` 按钮
- 状态提示文字 - 状态提示文字
- 每一行达人前面的勾选框 - 每一行达人前面的勾选框
其中: 其中:
- `导出列表CSV`:把当前选择的数据导出为表格文件 - `导出选中达人数据`:导出已勾选达人,包含内容数据、效果预估、画像等维度
- `提交批次`:把当前选择的数据提交为批次 - `提交批次`:把当前选择的数据提交为批次
--- ---
@ -215,13 +215,25 @@ https://xingtu.cn/ad/creator/market
规则说明: 规则说明:
- 如果你勾选了达人,再点击导出或提交,系统会优先处理你勾选的这些达人 - 如果你勾选了达人,再点击导出或提交,系统会优先处理你勾选的这些达人
- 如果你没有勾选任何达人,则默认按当前导出范围处理全部达人 - 导出达人数据必须先勾选达人
- 提交批次时,如果你没有勾选任何达人,则默认按当前导出范围处理全部达人
--- ---
## 九、导出 CSV 的方法 ## 九、导出达人数据 CSV 的方法
### 1. 选择导出范围 导出达人数据 CSV 用来导出内容数据、效果预估、画像和秒思 api 数据。
### 1. 勾选达人
导出达人数据必须先勾选达人。
原因:
- 导出达人数据会额外读取达人详情页数据
- 为了避免请求太多,只处理你勾选的达人
### 2. 选择导出范围
在插件工具栏中,你会看到导出范围下拉框,可选: 在插件工具栏中,你会看到导出范围下拉框,可选:
@ -233,19 +245,49 @@ https://xingtu.cn/ad/creator/market
如果选择 `自定义`,需要再输入页数。 如果选择 `自定义`,需要再输入页数。
### 2. 如果只想导出部分达人 ### 3. 可选:选择需要导出的字段
先勾选你想要的达人,再点击导出。 如果只想导出一部分字段,点击:
这样导出的 CSV 只会包含你勾选的人。 - `选择字段`
### 3. 点击导出 在弹出的窗口里:
1. 勾选需要的字段
2. 取消不需要的字段
3. 点击 `保存`
基础字段会固定保留,例如:
- 达人ID
- 达人名称
- 导出状态
- 失败原因
保存后,下次再导出 CSV会自动沿用这次勾选结果不需要重新勾选。
### 4. 点击导出
点击: 点击:
- `导出列表CSV` - `导出选中达人数据`
### 4. 等待导出完成 如果已经有达人星图 ID 列表,也可以点击:
- `按星图ID导出`
然后把达人 ID 粘贴进去,每行一个。
### 5. 导出内容
CSV 会包含:
- 内容数据
- 效果预估
- 画像
- 秒思 api 数据
### 6. 等待导出完成
页面上会显示状态,例如: 页面上会显示状态,例如:
@ -264,58 +306,6 @@ https://xingtu.cn/ad/creator/market
--- ---
## 十、导出画像 CSV 的方法
画像 CSV 用来导出达人画像、内容数据、效果预估和秒思 api 数据。
### 1. 勾选达人
画像导出必须先勾选达人。
原因:
- 画像导出会额外读取达人详情页数据
- 为了避免请求太多,只处理你勾选的达人
### 2. 可选:选择需要导出的字段
如果只想导出一部分画像字段,点击:
- `选择画像字段`
在弹出的窗口里:
1. 勾选需要的字段
2. 取消不需要的字段
3. 点击 `保存`
基础字段会固定保留,例如:
- 达人ID
- 达人名称
- 导出状态
- 失败原因
保存后,下次再导出画像 CSV会自动沿用这次勾选结果不需要重新勾选。
### 3. 点击导出
勾选达人后,点击:
- `导出选中达人画像`
如果已经有达人星图 ID 列表,也可以点击:
- `按星图ID导出画像`
然后把达人 ID 粘贴进去,每行一个。
### 4. 等待下载
导出完成后,浏览器会自动下载 CSV 文件。
---
## 十一、提交批次的方法 ## 十一、提交批次的方法
### 1. 选择范围 ### 1. 选择范围
@ -518,7 +508,7 @@ https://xingtu.cn/ad/creator/market
4. 打开星图达人市场页 4. 打开星图达人市场页
5. 等待页面数据加载完成 5. 等待页面数据加载完成
6. 先勾选需要的人,或直接选择范围 6. 先勾选需要的人,或直接选择范围
7. 需要表格时点 `导出列表CSV` 7. 需要表格时点 `导出选中达人数据`
8. 需要进入后续流程时点 `提交批次` 8. 需要进入后续流程时点 `提交批次`
--- ---

View File

@ -72,51 +72,43 @@ https://xingtu.cn/ad/creator/market
## 📝 主要功能 ## 📝 主要功能
### 1⃣ 导出基础数据(基础CSV ### 1⃣ 导出达人数据(CSV
- 勾选你想导出的达人(不勾就选全部) 当你需要导出达人的内容数据、效果预估、画像时使用:
- 先勾选你想导出数据的达人
- 选择范围:当前页 / 前5页 / 全部 - 选择范围:当前页 / 前5页 / 全部
- 点击 **"导出列表CSV"** - 点击 **"导出选中达人数据"**
- 文件自动下载到电脑的"下载"文件夹
### 2⃣ 导出画像数据画像CSV
当你需要导出达人的画像、内容数据、效果预估时使用:
- 先勾选你想导出画像的达人
- 选择范围:当前页 / 前5页 / 全部
- 点击 **"导出选中达人画像"**
- 等待下载完成 - 等待下载完成
- 文件自动下载到电脑的"下载"文件夹 - 文件自动下载到电脑的"下载"文件夹
⚠️ **重要**画像导出必须先勾选达人,因为它会额外请求达人详情页数据,不能默认导出全部。 ⚠️ **重要**:导出达人数据必须先勾选达人,因为它会额外请求达人详情页数据,不能默认导出全部。
**画像CSV包含**
- 观众画像、粉丝画像、铁粉画像
- 内容数据:个人视频/星图视频的播放量中位数、完播率、互动率、发布作品、平均时长、平均点赞、平均评论、平均转发 - 内容数据:个人视频/星图视频的播放量中位数、完播率、互动率、发布作品、平均时长、平均点赞、平均评论、平均转发
- 效果预估不同视频时长的预期CPM、预期CPE、预期播放量、爆文率 - 效果预估不同视频时长的预期CPM、预期CPE、预期播放量、爆文率
- 观众画像、粉丝画像、铁粉画像
- 秒思api数据看后搜率、看后搜数、新增A3数、新增A3率、CPA3、cp_search - 秒思api数据看后搜率、看后搜数、新增A3数、新增A3率、CPA3、cp_search
**只导出部分字段** **只导出部分字段**
- 点击 **"选择画像字段"** - 点击 **"选择字段"**
- 勾选你需要的字段,取消不需要的字段 - 勾选你需要的字段,取消不需要的字段
- 点击 **"保存"** - 点击 **"保存"**
- 再点击 **"导出选中达人画像"** 或 **"按星图ID导出画像"** - 再点击 **"导出选中达人数据"** 或 **"按星图ID导出"**
说明达人ID、达人名称、导出状态、失败原因等基础字段会固定保留你保存过一次后下次导出会自动沿用这次勾选结果不需要重新勾选。 说明达人ID、达人名称、导出状态、失败原因等基础字段会固定保留你保存过一次后下次导出会自动沿用这次勾选结果不需要重新勾选。
### 3⃣ 按ID导出画像数据 ### 2⃣ 按ID导出达人数据
当你想批量查询特定达人ID的画像数据时使用: 当你想批量查询特定达人ID的数据时使用
- 点击 **"按星图ID导出画像"** - 点击 **"按星图ID导出"**
- 在弹出的对话框中输入达人ID每行一个 - 在弹出的对话框中输入达人ID每行一个
- 点击确认 - 点击确认
- 等待下载完成 - 等待下载完成
**适用场景**已知一批达人星图ID需要批量导出这些达人的画像CSV。 **适用场景**已知一批达人星图ID需要批量导出这些达人的CSV。
### 4️⃣ 提交批次 ### 3️⃣ 提交批次
- 勾选你想提交的达人 - 勾选你想提交的达人
- 点击 **"提交批次"** - 点击 **"提交批次"**

View File

@ -25,7 +25,7 @@ export function promptForAudienceProfileFields(
applyTitleStyles(title); applyTitleStyles(title);
const hint = document.createElement("p"); const hint = document.createElement("p");
hint.textContent = "基础字段会固定保留。取消勾选后,本次及后续画像CSV将不包含对应列。"; hint.textContent = "基础字段会固定保留。取消勾选后,本次及后续CSV将不包含对应列。";
applyHintStyles(hint); applyHintStyles(hint);
const toolbar = document.createElement("div"); const toolbar = document.createElement("div");

View File

@ -8,7 +8,7 @@ export function promptForAuthorIds(document: Document): Promise<string | null> {
applyDialogStyles(dialog); applyDialogStyles(dialog);
const title = document.createElement("h2"); const title = document.createElement("h2");
title.textContent = "按星图ID导出画像CSV"; title.textContent = "按星图ID导出";
applyTitleStyles(title); applyTitleStyles(title);
const textarea = document.createElement("textarea"); const textarea = document.createElement("textarea");
@ -17,7 +17,7 @@ export function promptForAuthorIds(document: Document): Promise<string | null> {
applyTextareaStyles(textarea); applyTextareaStyles(textarea);
const hint = document.createElement("p"); const hint = document.createElement("p");
hint.textContent = "粘贴客户提供的达人星图ID确认后将批量导出画像和商业能力数据。"; hint.textContent = "粘贴客户提供的达人星图ID确认后将批量导出达人数据。";
applyHintStyles(hint); applyHintStyles(hint);
const actions = document.createElement("div"); const actions = document.createElement("div");

View File

@ -228,7 +228,7 @@ export function createMarketController(options: CreateMarketControllerOptions) {
onExportAudienceProfile: async () => { onExportAudienceProfile: async () => {
syncSelectionStateFromDom(); syncSelectionStateFromDom();
if (selectedAuthorIds.size === 0) { if (selectedAuthorIds.size === 0) {
setToolbarExportStatus(toolbar, "请先勾选需要导出画像的达人"); setToolbarExportStatus(toolbar, "请先勾选需要导出数据的达人");
return; return;
} }
@ -359,7 +359,7 @@ export function createMarketController(options: CreateMarketControllerOptions) {
saveAudienceProfileSelectedHeaders(nextHeaders); saveAudienceProfileSelectedHeaders(nextHeaders);
setToolbarExportStatus( setToolbarExportStatus(
toolbar, toolbar,
`画像字段已保存(已选 ${nextHeaders.length}/${readAudienceProfileSelectableHeaders().length} 个字段)` `字段已保存(已选 ${nextHeaders.length}/${readAudienceProfileSelectableHeaders().length} 个字段)`
); );
}, },
onSubmitBatch: async () => { onSubmitBatch: async () => {

View File

@ -79,29 +79,29 @@ 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.hidden = true;
exportButton.title = "导出当前达人列表中的基础字段和秒思指标"; exportButton.tabIndex = -1;
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 = "导出选中达人画像"; audienceProfileExportButton.textContent = "导出选中达人数据";
audienceProfileExportButton.title = 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导出画像"; audienceProfileByIdExportButton.textContent = "按星图ID导出";
audienceProfileByIdExportButton.title = audienceProfileByIdExportButton.title =
"粘贴达人星图ID后批量导出画像数据,不依赖当前列表勾选"; "粘贴达人星图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 = audienceProfileFieldButton.title =
"勾选本次画像CSV需要导出的字段设置会自动保存"; "勾选本次CSV需要导出的字段设置会自动保存";
const batchSubmitButton = document.createElement("button"); const batchSubmitButton = document.createElement("button");
batchSubmitButton.type = "button"; batchSubmitButton.type = "button";
@ -502,7 +502,6 @@ function applyNativeControlStyles(
findNativeActionButton(document, "导出"); findNativeActionButton(document, "导出");
if (nativeButton) { if (nativeButton) {
controls.exportButton.className = nativeButton.className;
controls.audienceProfileExportButton.className = nativeButton.className; controls.audienceProfileExportButton.className = nativeButton.className;
controls.audienceProfileByIdExportButton.className = nativeButton.className; controls.audienceProfileByIdExportButton.className = nativeButton.className;
controls.audienceProfileFieldButton.className = nativeButton.className; controls.audienceProfileFieldButton.className = nativeButton.className;
@ -510,7 +509,6 @@ function applyNativeControlStyles(
} }
[ [
controls.exportButton,
controls.audienceProfileExportButton, controls.audienceProfileExportButton,
controls.audienceProfileByIdExportButton, controls.audienceProfileByIdExportButton,
controls.audienceProfileFieldButton, controls.audienceProfileFieldButton,
@ -565,7 +563,6 @@ function ensurePluginActionButtonTheme(document: Document): void {
const style = document.createElement("style"); const style = document.createElement("style");
style.id = PLUGIN_ACTION_BUTTON_STYLE_ID; style.id = PLUGIN_ACTION_BUTTON_STYLE_ID;
style.textContent = ` style.textContent = `
[data-plugin-export="button"]:hover:not(:disabled),
[data-plugin-export-audience-profile="button"]:hover:not(:disabled), [data-plugin-export-audience-profile="button"]:hover:not(:disabled),
[data-plugin-export-audience-profile-by-id="button"]:hover:not(:disabled), [data-plugin-export-audience-profile-by-id="button"]:hover:not(:disabled),
[data-plugin-audience-profile-fields="button"]:hover:not(:disabled), [data-plugin-audience-profile-fields="button"]:hover:not(:disabled),
@ -574,7 +571,6 @@ function ensurePluginActionButtonTheme(document: Document): void {
border-color: #6d1627 !important; border-color: #6d1627 !important;
} }
[data-plugin-export="button"]:active:not(:disabled),
[data-plugin-export-audience-profile="button"]:active:not(:disabled), [data-plugin-export-audience-profile="button"]:active:not(:disabled),
[data-plugin-export-audience-profile-by-id="button"]:active:not(:disabled), [data-plugin-export-audience-profile-by-id="button"]:active:not(:disabled),
[data-plugin-audience-profile-fields="button"]:active:not(:disabled), [data-plugin-audience-profile-fields="button"]:active:not(:disabled),
@ -584,7 +580,6 @@ function ensurePluginActionButtonTheme(document: Document): void {
transform: translateY(1px); transform: translateY(1px);
} }
[data-plugin-export="button"]:focus-visible,
[data-plugin-export-audience-profile="button"]:focus-visible, [data-plugin-export-audience-profile="button"]:focus-visible,
[data-plugin-export-audience-profile-by-id="button"]:focus-visible, [data-plugin-export-audience-profile-by-id="button"]:focus-visible,
[data-plugin-audience-profile-fields="button"]:focus-visible, [data-plugin-audience-profile-fields="button"]:focus-visible,
@ -593,7 +588,6 @@ function ensurePluginActionButtonTheme(document: Document): void {
box-shadow: 0 0 0 3px rgba(127, 29, 45, 0.2) !important; box-shadow: 0 0 0 3px rgba(127, 29, 45, 0.2) !important;
} }
[data-plugin-export="button"]:disabled,
[data-plugin-export-audience-profile="button"]:disabled, [data-plugin-export-audience-profile="button"]:disabled,
[data-plugin-export-audience-profile-by-id="button"]:disabled, [data-plugin-export-audience-profile-by-id="button"]:disabled,
[data-plugin-audience-profile-fields="button"]:disabled, [data-plugin-audience-profile-fields="button"]:disabled,

View File

@ -325,7 +325,10 @@ describe("market-content-entry", () => {
expect(document.body.firstElementChild).not.toBe(toolbar); expect(document.body.firstElementChild).not.toBe(toolbar);
expect(document.querySelector('[data-plugin-export-range="select"]')).not.toBeNull(); expect(document.querySelector('[data-plugin-export-range="select"]')).not.toBeNull();
expect(document.querySelector('[data-plugin-export="button"]')).not.toBeNull(); expect(
(document.querySelector('[data-plugin-export="button"]') as HTMLButtonElement | null)
?.hidden
).toBe(true);
expect( expect(
document.querySelector('[data-plugin-export-audience-profile="button"]') document.querySelector('[data-plugin-export-audience-profile="button"]')
).not.toBeNull(); ).not.toBeNull();
@ -335,9 +338,6 @@ describe("market-content-entry", () => {
expect(document.querySelector('[data-plugin-batch-submit="button"]')).not.toBeNull(); expect(document.querySelector('[data-plugin-batch-submit="button"]')).not.toBeNull();
expect(document.querySelector('[data-plugin-export-status="text"]')).not.toBeNull(); expect(document.querySelector('[data-plugin-export-status="text"]')).not.toBeNull();
const exportButton = document.querySelector(
'[data-plugin-export="button"]'
) as HTMLButtonElement | null;
const batchSubmitButton = document.querySelector( const batchSubmitButton = document.querySelector(
'[data-plugin-batch-submit="button"]' '[data-plugin-batch-submit="button"]'
) as HTMLButtonElement | null; ) as HTMLButtonElement | null;
@ -350,26 +350,22 @@ describe("market-content-entry", () => {
const audienceProfileFieldButton = document.querySelector( const audienceProfileFieldButton = document.querySelector(
'[data-plugin-audience-profile-fields="button"]' '[data-plugin-audience-profile-fields="button"]'
) as HTMLButtonElement | null; ) as HTMLButtonElement | null;
expect(exportButton?.textContent).toBe("导出列表CSV"); expect(audienceProfileExportButton?.textContent).toBe("导出选中达人数据");
expect(exportButton?.title).toBe("导出当前达人列表中的基础字段和秒思指标");
expect(audienceProfileExportButton?.textContent).toBe("导出选中达人画像");
expect(audienceProfileExportButton?.title).toBe( expect(audienceProfileExportButton?.title).toBe(
"仅导出已勾选达人,包含画像、内容数据、效果预估等字段" "仅导出已勾选达人,包含内容数据、效果预估、画像等维度"
); );
expect(audienceProfileByIdExportButton?.textContent).toBe("按星图ID导出画像"); expect(audienceProfileByIdExportButton?.textContent).toBe("按星图ID导出");
expect(audienceProfileByIdExportButton?.title).toBe( expect(audienceProfileByIdExportButton?.title).toBe(
"粘贴达人星图ID后批量导出画像数据,不依赖当前列表勾选" "粘贴达人星图ID后批量导出达人数据,不依赖当前列表勾选"
); );
expect(audienceProfileFieldButton?.textContent).toBe("选择画像字段"); expect(audienceProfileFieldButton?.textContent).toBe("选择字段");
expect(audienceProfileFieldButton?.title).toBe( expect(audienceProfileFieldButton?.title).toBe(
"勾选本次画像CSV需要导出的字段设置会自动保存" "勾选本次CSV需要导出的字段设置会自动保存"
); );
expect(batchSubmitButton?.title).toBe("将当前选中的达人提交到后续业务批次"); expect(batchSubmitButton?.title).toBe("将当前选中的达人提交到后续业务批次");
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)");
expect(audienceProfileByIdExportButton?.style.backgroundColor).toBe("rgb(127, 29, 45)"); expect(audienceProfileByIdExportButton?.style.backgroundColor).toBe("rgb(127, 29, 45)");
expect(exportButton?.style.color).toBe("rgb(255, 255, 255)");
expect(batchSubmitButton?.style.color).toBe("rgb(255, 255, 255)"); expect(batchSubmitButton?.style.color).toBe("rgb(255, 255, 255)");
expect(audienceProfileExportButton?.style.color).toBe("rgb(255, 255, 255)"); expect(audienceProfileExportButton?.style.color).toBe("rgb(255, 255, 255)");
expect(audienceProfileByIdExportButton?.style.color).toBe("rgb(255, 255, 255)"); expect(audienceProfileByIdExportButton?.style.color).toBe("rgb(255, 255, 255)");
@ -1642,7 +1638,7 @@ describe("market-content-entry", () => {
expect(buildAudienceProfileCsv).not.toHaveBeenCalled(); expect(buildAudienceProfileCsv).not.toHaveBeenCalled();
expect( expect(
document.querySelector('[data-plugin-export-status="text"]')?.textContent document.querySelector('[data-plugin-export-status="text"]')?.textContent
).toContain("请先勾选需要导出画像的达人"); ).toContain("请先勾选需要导出数据的达人");
}); });
test("audience profile export loads profiles only for selected creators", async () => { test("audience profile export loads profiles only for selected creators", async () => {
@ -1954,7 +1950,7 @@ describe("market-content-entry", () => {
expect(savedHeaders).toContain("内容数据-个人视频-播放量中位数"); expect(savedHeaders).toContain("内容数据-个人视频-播放量中位数");
expect( expect(
document.querySelector('[data-plugin-export-status="text"]')?.textContent document.querySelector('[data-plugin-export-status="text"]')?.textContent
).toContain("画像字段已保存"); ).toContain("字段已保存");
}); });
test( test(