siluzan-tso-cli 1.1.14-beta.6 → 1.1.14-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
51
51
  siluzan-tso init --force # 强制覆盖已存在文件
52
52
  ```
53
53
 
54
- > **注意**:当前为测试版(1.1.14-beta.6),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
+ > **注意**:当前为测试版(1.1.14-beta.8),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
55
55
 
56
56
  | 助手 | 建议 `--ai` |
57
57
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -2872,8 +2872,9 @@ function fmt(d) {
2872
2872
  }
2873
2873
  function defaultDateRange() {
2874
2874
  const end = /* @__PURE__ */ new Date();
2875
- const start = /* @__PURE__ */ new Date();
2876
- start.setDate(start.getDate() - 7);
2875
+ end.setDate(end.getDate() - 1);
2876
+ const start = new Date(end);
2877
+ start.setDate(start.getDate() - 6);
2877
2878
  return { startDate: fmt(start), endDate: fmt(end) };
2878
2879
  }
2879
2880
  async function fetchBalanceMap(media, accountIds, config, startDate, endDate, verbose) {
@@ -6935,6 +6936,12 @@ function toDisplayMoney(raw) {
6935
6936
  if (!Number.isFinite(n)) return null;
6936
6937
  return n / 100;
6937
6938
  }
6939
+ function toCentAmount(displayValue) {
6940
+ if (!Number.isFinite(displayValue)) {
6941
+ throw new Error(`toCentAmount: \u8F93\u5165\u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\uFF0C\u6536\u5230 ${displayValue}`);
6942
+ }
6943
+ return Math.round(displayValue * 100);
6944
+ }
6938
6945
  function adgroupListUrl(googleApiUrl, account, startDate, endDate) {
6939
6946
  const params = new URLSearchParams();
6940
6947
  params.set("startDate", toGoogleDate(startDate, -30));
@@ -8139,8 +8146,8 @@ async function runAdGroupEdit(opts) {
8139
8146
  }
8140
8147
  const body = { ...adgroup };
8141
8148
  if (hasName) body["name"] = opts.name.trim();
8142
- if (hasMax) body["maxCPCAmount"] = Math.round(opts.maxCPCAmount);
8143
- if (hasTcpa) body["targetCpaAmount"] = Math.round(opts.targetCpaAmount);
8149
+ if (hasMax) body["maxCPCAmount"] = toCentAmount(opts.maxCPCAmount);
8150
+ if (hasTcpa) body["targetCpaAmount"] = toCentAmount(opts.targetCpaAmount);
8144
8151
  const putUrl = `${googleApiUrl}/adgroupnmanagement/adgroup/${opts.account}/${opts.id}`;
8145
8152
  try {
8146
8153
  await apiFetch2(putUrl, config, { method: "PUT", body: JSON.stringify(body) }, opts.verbose);
@@ -8341,11 +8348,12 @@ async function runAdCampaignEdit(opts) {
8341
8348
  }
8342
8349
  const body = { ...campaign };
8343
8350
  if (opts.name !== void 0) body["name"] = opts.name;
8344
- if (opts.budget !== void 0) body["budget"] = opts.budget;
8351
+ if (opts.budget !== void 0) body["budget"] = toCentAmount(opts.budget);
8345
8352
  if (opts.biddingStrategy !== void 0) body["biddingStrategyTypeV2"] = opts.biddingStrategy;
8346
8353
  if (opts.targetSpendBidCeiling !== void 0)
8347
- body["targetSpend_BidCeilingAmount"] = opts.targetSpendBidCeiling;
8348
- if (opts.targetCpa !== void 0) body["targetCpa_BidingAmount"] = opts.targetCpa;
8354
+ body["targetSpend_BidCeilingAmount"] = toCentAmount(opts.targetSpendBidCeiling);
8355
+ if (opts.targetCpa !== void 0)
8356
+ body["targetCpa_BidingAmount"] = toCentAmount(opts.targetCpa);
8349
8357
  if (opts.targetSearchNetwork !== void 0)
8350
8358
  body["targetSearchNetwork"] = opts.targetSearchNetwork;
8351
8359
  if (opts.targetContentNetwork !== void 0)
@@ -13387,7 +13395,19 @@ adCmd.command("campaign-create").description(
13387
13395
  });
13388
13396
  }
13389
13397
  );
13390
- adCmd.command("campaign-edit").description("\u7F16\u8F91\u5E7F\u544A\u7CFB\u5217\uFF08\u540D\u79F0/\u9884\u7B97/\u51FA\u4EF7\u7B56\u7565/\u6295\u653E\u7F51\u7EDC\uFF0C\u81F3\u5C11\u4F20\u4E00\u4E2A\u4FEE\u6539\u9879\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").requiredOption("--id <campaignId>", "\u5E7F\u544A\u7CFB\u5217 ID").option("--name <name>", "\u65B0\u540D\u79F0").option("--budget <amount>", "\u65B0\u9884\u7B97\uFF08\u6700\u5C0F\u8D27\u5E01\u5355\u4F4D\uFF0C\u5982 100000 = 1 USD\uFF09", parseInt).option("--bidding <strategy>", "\u51FA\u4EF7\u7B56\u7565\uFF1ATARGET_SPEND | TARGET_CPA | TARGET_ROAS | MANUAL_CPC").option("--bid-ceiling <amount>", "TARGET_SPEND \u51FA\u4EF7\u4E0A\u9650\uFF08\u6700\u5C0F\u8D27\u5E01\u5355\u4F4D\uFF0C0=\u4E0D\u9650\uFF09", parseInt).option("--target-cpa <amount>", "TARGET_CPA \u76EE\u6807 CPA\uFF08\u6700\u5C0F\u8D27\u5E01\u5355\u4F4D\uFF09", parseInt).option(
13398
+ adCmd.command("campaign-edit").description("\u7F16\u8F91\u5E7F\u544A\u7CFB\u5217\uFF08\u540D\u79F0/\u9884\u7B97/\u51FA\u4EF7\u7B56\u7565/\u6295\u653E\u7F51\u7EDC\uFF0C\u81F3\u5C11\u4F20\u4E00\u4E2A\u4FEE\u6539\u9879\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").requiredOption("--id <campaignId>", "\u5E7F\u544A\u7CFB\u5217 ID").option("--name <name>", "\u65B0\u540D\u79F0").option(
13399
+ "--budget <amount>",
13400
+ "\u65B0\u9884\u7B97\uFF0C\u4E3B\u5E01\u79CD\u91D1\u989D\uFF08\u5982 100 \u8868\u793A \xA5100\uFF1B\u652F\u6301\u5C0F\u6570\uFF1BCLI \u5185\u90E8\u81EA\u52A8 \xD7100 \u5199\u5165\u300C\u5206\u300D\u5B57\u6BB5\uFF09",
13401
+ parseFloat
13402
+ ).option("--bidding <strategy>", "\u51FA\u4EF7\u7B56\u7565\uFF1ATARGET_SPEND | TARGET_CPA | TARGET_ROAS | MANUAL_CPC").option(
13403
+ "--bid-ceiling <amount>",
13404
+ "TARGET_SPEND \u51FA\u4EF7\u4E0A\u9650\uFF0C\u4E3B\u5E01\u79CD\u91D1\u989D\uFF080 = \u4E0D\u9650\uFF1BCLI \u5185\u90E8 \xD7100 \u5199\u5165\uFF09",
13405
+ parseFloat
13406
+ ).option(
13407
+ "--target-cpa <amount>",
13408
+ "TARGET_CPA \u76EE\u6807 CPA\uFF0C\u4E3B\u5E01\u79CD\u91D1\u989D\uFF08CLI \u5185\u90E8 \xD7100 \u5199\u5165\uFF09",
13409
+ parseFloat
13410
+ ).option(
13391
13411
  "--search-network <bool>",
13392
13412
  "\u6295\u653E\u5230 Google \u641C\u7D22\uFF1Atrue | false",
13393
13413
  (v) => v === "true"
@@ -13423,11 +13443,11 @@ adCmd.command("adgroup-rename").description("\u4FEE\u6539\u5E7F\u544A\u7EC4\u540
13423
13443
  );
13424
13444
  adCmd.command("adgroup-edit").description("\u7F16\u8F91\u5E7F\u544A\u7EC4\uFF08\u540D\u79F0\u3001\u6700\u9AD8 CPC\u3001\u7EC4\u7EA7\u76EE\u6807 CPA\uFF1B\u81F3\u5C11\u4F20\u4E00\u9879\uFF1B\u4E0E\u7F51\u5173 PUT \u4E00\u81F4\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").requiredOption("--id <adgroupId>", "\u5E7F\u544A\u7EC4 ID").option("--name <name>", "\u65B0\u540D\u79F0").option(
13425
13445
  "--max-cpc <n>",
13426
- "\u6700\u9AD8 CPC\uFF0C\u4E0E ad groups --json \u7684 maxCPCAmount \u540C\u53E3\u5F84\uFF08\u4E3B\u5E01\u79CD\u91D1\u989D\xD7100\uFF0C\u89C1 references/google-ads.md\uFF09",
13446
+ "\u6700\u9AD8 CPC\uFF0C\u4E3B\u5E01\u79CD\u91D1\u989D\uFF08\u5982 1.5 \u8868\u793A \xA51.50\uFF1BCLI \u5185\u90E8 \xD7100 \u5199\u5165\u300C\u5206\u300D\u5B57\u6BB5\uFF09",
13427
13447
  parseFloat
13428
13448
  ).option(
13429
13449
  "--target-cpa <n>",
13430
- "\u7EC4\u7EA7\u76EE\u6807 CPA\uFF0C\u4E0E ad groups --json \u7684 targetCpaAmount \u540C\u53E3\u5F84\uFF08\xD7100 \u5206\u5355\u4F4D\uFF09",
13450
+ "\u7EC4\u7EA7\u76EE\u6807 CPA\uFF0C\u4E3B\u5E01\u79CD\u91D1\u989D\uFF08CLI \u5185\u90E8 \xD7100 \u5199\u5165\u300C\u5206\u300D\u5B57\u6BB5\uFF09",
13431
13451
  parseFloat
13432
13452
  ).option("--start <date>", "\u5217\u8868\u67E5\u8BE2\u8D77\u59CB\u65E5\u671F YYYY-MM-DD").option("--end <date>", "\u5217\u8868\u67E5\u8BE2\u7ED3\u675F\u65E5\u671F YYYY-MM-DD").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
13433
13453
  async (opts) => {
@@ -59,8 +59,8 @@ allowed-tools: Bash(siluzan-tso:*) Read
59
59
  | `references/account-analytics.md` | 广告平台账户分析数据拉取与分析/诊断报告模板 |
60
60
  | `references/optimize.md` | AI 优化建议记录、详情与历史查询 |
61
61
  | `references/clue.md` | TikTok / Meta 线索表单 |
62
- | `references/forewarning.md` | siluzan提供的全流程的智能预警规则与通知服务,功能有限、你只需要负责创建,剩下的由Siluzan服务来完成 |
63
- | `references/hosted-automation-user-catalog.md` | (推荐!)更强大的智能预警,由你全流程控制(创建+定时检测+通知用户)基础包括,预算/ROI 自控、异常监控、自动优化、自动化风控。详情请阅读这个文件`references/hosted-automation-user-catalog.md`|
62
+ | `references/forewarning.md` | Siluzan提供的全流程的智能预警规则与通知服务,功能有限、你只需要负责创建,剩下的由Siluzan服务来完成,不推荐使用这个来处理预警 |
63
+ | `references/hosted-automation-user-catalog.md` | (推荐用于预警处理)更强大的智能预警,由你全流程控制(创建+定时检测+通知用户)基础包括,预算/ROI 自控、异常监控、自动优化、自动化风控。详情请阅读这个文件`references/hosted-automation-user-catalog.md`|
64
64
  | `references/finance.md` | 转账、开票、发票抬头、充值网页引导 |
65
65
  | `report-templates/report-template.html` | 默认 HTML 报告样式参考 |
66
66
 
@@ -186,10 +186,10 @@ allowed-tools: Bash(siluzan-tso:*) Read
186
186
 
187
187
  | 场景 | 允许的默认窗口 |
188
188
  | ----------------------- | ----------------------------------------------------- |
189
- | 日常投放巡检 / 余额扫描 | `now - 7d` ~ `now`(本地时间) |
189
+ | 日常投放巡检 / 余额扫描 | `now - 7d` ~ `now - 1d`(本地时间) |
190
190
  | 周报 | 上一个完整自然周(周一 00:00 ~ 周日 23:59) |
191
191
  | 月报 | 上一个完整自然月(1 号 ~ 月末) |
192
- | Google 关键词/系列分析 | `now - 30d` ~ `now`(与 TSO Google 接口最小窗口对齐) |
192
+ | Google 关键词/系列分析 | `now - 30d` ~ `now - 1d`(与 TSO Google 接口最小窗口对齐) |
193
193
  | MetaAd 账户分析 | 不得默认,必须问(Meta 接口对窗口敏感) |
194
194
 
195
195
  ### 金额与货币单位硬约束
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.14-beta.6",
4
- "publishedAt": 1777255792643
3
+ "version": "1.1.14-beta.8",
4
+ "publishedAt": 1777367679688
5
5
  }
@@ -511,10 +511,11 @@ siluzan-tso ad batch get --id <taskId>
511
511
  siluzan-tso ad campaigns -a <CID> --json
512
512
 
513
513
  # 切换到 Target CPA(数据充足后)
514
+ # --target-cpa 是「主币种金额」,CLI 内部自动 ×100 写入;50 = 50 USD(不是微单位 5000)
514
515
  siluzan-tso ad campaign-edit -a <CID> --id <系列ID> \
515
- --bidding TARGET_CPA --target-cpa 5000 # 50 USD (微单位)
516
+ --bidding TARGET_CPA --target-cpa 50
516
517
 
517
- # 切换到 Target ROAS
518
+ # 切换到 Target ROAS(ROAS 是比例,不是金额,无需 ×100)
518
519
  siluzan-tso ad campaign-edit -a <CID> --id <系列ID> \
519
520
  --bidding TARGET_ROAS --target-roas 3.0
520
521
  ```
@@ -258,32 +258,37 @@ siluzan-tso ad adgroup-status -a 6326027735 --id adgroup_001 --status Enabled
258
258
 
259
259
  ### 广告组编辑(名称 / 最高 CPC / 组级目标 CPA)
260
260
 
261
- `adgroup-status`、`adgroup-rename` 相同:先用 **`ad groups … --json`** 查看当前 **`maxCPCAmount`**、**`targetCpaAmount`** 等,再用本命令只改传入的字段(由 CLI 与 `siluzan-tso` 合并提交)。
261
+ 先用 **`ad groups … --json`** 查看当前的 **`maxCPCAmountDisplay`**、**`targetCpaAmountDisplay`**(主币种金额)等,再用本命令只改传入的字段。
262
262
 
263
263
  ```bash
264
264
  siluzan-tso ad adgroup-edit \
265
265
  -a <accountId> \
266
266
  --id <adGroupId> \
267
267
  [--name <新名称>] \
268
- [--max-cpc <n>] \
269
- [--target-cpa <n>] \
268
+ [--max-cpc <主币种金额>] \
269
+ [--target-cpa <主币种金额>] \
270
270
  [--start <YYYY-MM-DD>] [--end <YYYY-MM-DD>]
271
271
  ```
272
272
 
273
+ > **金额单位(必读)**:所有金额参数均按 **主币种金额** 传入(如 `1.5` 表示 ¥1.50);CLI 内部 `Math.round(value × 100)` 写入后端「分」字段,与 `ad campaign-edit`、前端表单完全一致。**禁止** 按 Google micros(×1,000,000)填写。
274
+
273
275
  | 选项 | 说明 |
274
276
  |------|------|
275
- | `--max-cpc` | **`ad groups --json`** 中 **`maxCPCAmount`** 同一整数口径;与主币种展示关系见 **`maxCPCAmountDisplay`**(`SKILL.md` 金额硬规范)。 |
276
- | `--target-cpa` | **`ad groups --json`** 中 **`targetCpaAmount`** 同一整数口径。写入 **> 0** 的值才会更新组级目标 CPA;为 `0` 或不传则通常不改变该项。 |
277
+ | `--max-cpc` | 最高 CPC,主币种金额(与 `ad groups --json` 中 **`maxCPCAmountDisplay`** 对齐)。 |
278
+ | `--target-cpa` | 组级目标 CPA,主币种金额(与 `ad groups --json` 中 **`targetCpaAmountDisplay`** 对齐)。写入 **> 0** 才会更新。 |
277
279
  | `--name` | 新名称(可选)。 |
278
280
 
279
281
  **示例:**
280
282
 
281
283
  ```bash
282
- # 先取 JSON,用 maxCPCAmount / targetCpaAmount 算好新值后再写回
284
+ # 先取 JSON,读取 maxCPCAmountDisplay / targetCpaAmountDisplay(主币种金额)算新值后再写回
283
285
  siluzan-tso ad groups -a 6326027735 --json
284
286
 
285
- siluzan-tso ad adgroup-edit -a 6326027735 --id 195548094874 --max-cpc 200
286
- siluzan-tso ad adgroup-edit -a 6326027735 --id 195548094874 --target-cpa 5000 --name "核心词_降价后"
287
+ # 把最高 CPC 调整到 ¥2
288
+ siluzan-tso ad adgroup-edit -a 6326027735 --id 195548094874 --max-cpc 2
289
+
290
+ # 设置目标 CPA = ¥50,并改名
291
+ siluzan-tso ad adgroup-edit -a 6326027735 --id 195548094874 --target-cpa 50 --name "核心词_降价后"
287
292
  ```
288
293
 
289
294
  ---
@@ -618,11 +623,11 @@ siluzan-tso ad batch get --id <recordId>
618
623
  siluzan-tso ad batch update --id <recordId> [选项]
619
624
  ```
620
625
 
621
- | 选项 | 说明 |
622
- | ------------------------ | --------------------------------------------- |
623
- | `--budget <amount>` | 新预算(最小货币单位,如 `8500` = 85 CNY) |
624
- | `--url <url>` | 新推广链接 |
625
- | `--campaign-name <name>` | 新广告系列名称 |
626
+ | 选项 | 说明 |
627
+ | ------------------------ | ------------------------------------------------------------------- |
628
+ | `--budget <amount>` | 新日预算,主币种金额(如 `85` 表示 ¥85;CLI 内部自动 ×100 写入「分」) |
629
+ | `--url <url>` | 新推广链接 |
630
+ | `--campaign-name <name>` | 新广告系列名称 |
626
631
 
627
632
  ### publish — 发布草稿
628
633
 
@@ -814,33 +819,42 @@ siluzan-tso ad campaign-edit \
814
819
  -a <accountId> \
815
820
  --id <campaignId> \
816
821
  [--name <新名称>] \
817
- [--budget <预算(最小货币单位)>] \
822
+ [--budget <主币种金额>] \
818
823
  [--bidding <出价策略>] \
819
- [--bid-ceiling <出价上限>] \
824
+ [--bid-ceiling <主币种金额>] \
825
+ [--target-cpa <主币种金额>] \
820
826
  [--search-network true|false] \
821
827
  [--content-network true|false]
822
828
  ```
823
829
 
830
+ > **金额单位(必读)**:所有金额参数均按 **主币种金额**(如 `100` 表示 ¥100,支持小数 `10.5`)传入;CLI 内部 `Math.round(value × 100)` 写入后端「分」字段,与前端表单、`ad campaign-create`、`ad batch update` 完全一致。**禁止** 按 Google micros(×1,000,000)口径填写,会被后端按「分」解读,导致金额放大 10000 倍。
831
+
824
832
  | 选项 | 说明 |
825
833
  | ------------------- | ------------------------------------------------------------------------- |
826
834
  | `--name` | 新广告系列名称 |
827
- | `--budget` | 新预算,最小货币单位(如 100000 = 1 USD |
835
+ | `--budget` | 新日预算,主币种金额(如 `100` = ¥100;`10.5` = ¥10.50 |
828
836
  | `--bidding` | 出价策略:`TARGET_SPEND` \| `TARGET_CPA` \| `TARGET_ROAS` \| `MANUAL_CPC` |
829
- | `--bid-ceiling` | `TARGET_SPEND` 出价上限(最小货币单位,0 = 不限) |
830
- | `--target-cpa` | `TARGET_CPA` 目标 CPA |
837
+ | `--bid-ceiling` | `TARGET_SPEND` 出价上限,主币种金额(`0` = 不限) |
838
+ | `--target-cpa` | `TARGET_CPA` 目标 CPA,主币种金额 |
831
839
  | `--search-network` | 投放 Google 搜索:`true` \| `false` |
832
840
  | `--content-network` | 投放展示网络:`true` \| `false` |
833
841
 
834
842
  **示例:**
835
843
 
836
844
  ```bash
837
- # 修改名称和预算
845
+ # 修改名称和预算(日预算 ¥5000)
838
846
  siluzan-tso ad campaign-edit -a 6326027735 --id 23509626948 \
839
- --name "搜索-春季促销-2026" --budget 500000
847
+ --name "搜索-春季促销-2026" --budget 5000
848
+
849
+ # 在原预算基础上 +10 元(典型相对运算流程):
850
+ # 1) 先 GET 系列详情,读出 budgetDisplay(主币种)
851
+ # 2) 计算新值(主币种)= budgetDisplay + 10
852
+ # 3) 把新值(主币种)作为 --budget 传入;CLI 内部自动 ×100
853
+ siluzan-tso ad campaign-edit -a 6326027735 --id 23509626948 --budget 10.01
840
854
 
841
855
  # 切换出价策略为 TARGET_CPA,目标 CPA 2 USD
842
856
  siluzan-tso ad campaign-edit -a 6326027735 --id 23509626948 \
843
- --bidding TARGET_CPA --target-cpa 200000
857
+ --bidding TARGET_CPA --target-cpa 2
844
858
  ```
845
859
 
846
860
  ---
@@ -22,8 +22,8 @@ siluzan-tso balance-scan -m Google [--threshold-days <n>] [--min-balance <n>] [-
22
22
  |------|---------------------|
23
23
  | 账户 | `data.items[].mediaCustomerId`、`data.items[].name`、`data.items[].advertiserName` |
24
24
  | 余额(主币种金额,与平台余额接口一致) | **`data.items[].balance`**(由 `remainingAccountBudget` 计算而来) |
25
- | 近 7 日估算日均消耗 | **`data.items[].dailySpend`** |
26
- | 按余额÷日均估算的续航天数 | **`data.items[].remainingDays`**(消耗过低时可能为 `null`) |
25
+ | 近 7 日估算日均消耗 | **`data.items[].dailySpend`** = 近 7 日总消耗 / 7(窗口为 **[T-7, T-1]**,即截至昨天的 7 个自然日,**不含当天**,避免拉到当天未结算数据) |
26
+ | 按余额÷日均估算的续航天数 | **`data.items[].remainingDays`** = `balance / dailySpend`(消耗过低 < `minDailySpend` 时为 `null`) |
27
27
  | 建议充值额(按 `meta.thresholds.targetDaysForTopup` 目标) | **`data.items[].recommendedTopup`** |
28
28
  | 命中原因(阈值逻辑) | **`data.items[].hitReason`**:`low-days` \| `low-balance` \| `both` |
29
29
  | 币种 / 状态 / OAuth | `data.items[].currencyCode`、`data.items[].status`、`data.items[].invalidOAuthToken` |
@@ -52,25 +52,34 @@ siluzan-tso google-analysis campaign-hour -a <mediaCustomerId> --start <YYYY-MM-
52
52
 
53
53
  ## 最终操作
54
54
 
55
- **提高系列日预算**(主币种 / 微单位以 `google-ads.md`「ad campaign-edit」为准):
55
+ > **金额单位(关键)**:`ad campaign-edit` / `ad adgroup-edit` 所有金额参数均为 **主币种金额**(如 `100` 表示 ¥100,支持小数 `10.5`);CLI 内部自动 `Math.round(value × 100)` 写入「分」字段。详见 `references/google-ads.md`「ad campaign-edit」金额单位说明。
56
+ >
57
+ > **必须先用 `*Display` 字段取主币种当前值,加减后再传回**;不要把 `budget` / `targetCpaAmount` / `maxCPCAmount` 这些"分"字段当作主币种传给 CLI。
58
+
59
+ **提高系列日预算**(在原值基础上 +10 元的写法):
56
60
 
57
61
  ```bash
58
- siluzan-tso ad campaign-edit -a <mediaCustomerId> --id <campaignId> --budget <新值>
62
+ # 1) GET 取主币种当前值
63
+ CUR=$(siluzan-tso ad campaigns -a <mediaCustomerId> --json | node -e '...筛选 budgetDisplay')
64
+ # 2) 主币种 + 10
65
+ NEW=$(node -e "console.log((${CUR} + 10).toFixed(2))")
66
+ # 3) 主币种金额传回
67
+ siluzan-tso ad campaign-edit -a <mediaCustomerId> --id <campaignId> --budget ${NEW}
59
68
  ```
60
69
 
61
70
  **上调系列目标 CPA**(若策略为 tCPA 等):
62
71
 
63
72
  ```bash
64
- siluzan-tso ad campaign-edit -a <mediaCustomerId> --id <campaignId> --target-cpa <新值>
73
+ siluzan-tso ad campaign-edit -a <mediaCustomerId> --id <campaignId> --target-cpa <主币种金额>
65
74
  ```
66
75
 
67
76
  若策略在**组级**调目标 CPA:
68
77
 
69
78
  ```bash
70
- siluzan-tso ad adgroup-edit -a <mediaCustomerId> --id <adGroupId> --target-cpa <新值>
79
+ siluzan-tso ad adgroup-edit -a <mediaCustomerId> --id <adGroupId> --target-cpa <主币种金额>
71
80
  ```
72
81
 
73
- 写前务必先 **`ad campaigns --json` / `ad groups --json`** 取当前值,在宿主内按配置比例计算再写入。
82
+ 写前务必先 **`ad campaigns --json` / `ad groups --json`** 取当前值,**读取 `*Display` 字段**(主币种)后按配置比例计算,再以主币种金额传回。
74
83
 
75
84
  ---
76
85
 
@@ -107,28 +107,32 @@ siluzan-tso ad campaign-status -a <mediaCustomerId> --id <campaignId> --status E
107
107
  **系列(tCPA / 出价上限等)**:
108
108
 
109
109
  ```bash
110
- siluzan-tso ad campaign-edit -a <mediaCustomerId> --id <campaignId> --target-cpa <新值最小货币单位整数>
110
+ # 所有金额参数均为「主币种金额」(如 50 表示 ¥50);CLI 内部自动 ×100 写入「分」字段
111
+ siluzan-tso ad campaign-edit -a <mediaCustomerId> --id <campaignId> --target-cpa <新值(主币种)>
111
112
  # 或 eCPC / 最大化点击上限等:
112
- # siluzan-tso ad campaign-edit ... --bid-ceiling <整数> --bidding TARGET_SPEND
113
+ # siluzan-tso ad campaign-edit ... --bid-ceiling <主币种金额> --bidding TARGET_SPEND
113
114
  ```
114
115
 
115
- 参数与单位见 **`references/google-ads.md`**「ad campaign-edit」。
116
+ 参数与单位见 **`references/google-ads.md`**「ad campaign-edit」金额单位说明。
116
117
 
117
118
  **广告组**:
118
119
 
119
120
  ```bash
120
- siluzan-tso ad adgroup-edit -a <mediaCustomerId> --id <adGroupId> --target-cpa <与 groups --json 同口径>
121
+ siluzan-tso ad adgroup-edit -a <mediaCustomerId> --id <adGroupId> --target-cpa <主币种金额>
121
122
  # 或
122
- siluzan-tso ad adgroup-edit -a <mediaCustomerId> --id <adGroupId> --max-cpc <与 groups --json 同口径>
123
+ siluzan-tso ad adgroup-edit -a <mediaCustomerId> --id <adGroupId> --max-cpc <主币种金额>
123
124
  ```
124
125
 
125
126
  见 **`references/google-ads.md`**「广告组编辑」。
126
127
 
127
- 写前建议先 **`ad groups --json` / `ad campaigns --json`** 取当前值,在宿主内算新值(如下调 12%:`new = round(old * 0.88)`),再写入。
128
+ 写前**必须**先 **`ad groups --json` / `ad campaigns --json`** 取当前值,**读取 `*Display` 字段**(主币种金额,如 `targetCpaAmountDisplay`、`maxCPCAmountDisplay`、`budgetDisplay`),在宿主内按主币种算新值(如下调 12%:`newDisplay = round((oldDisplay * 0.88) * 100) / 100`),再以主币种金额作为 `--target-cpa` / `--max-cpc` / `--budget` 传回。
129
+ **严禁** 把 `targetCpaAmount` / `maxCPCAmount` / `budget` 这些「分」字段直接当作主币种金额传给 CLI——会被再 ×100 一次,金额放大 100 倍。
128
130
 
129
131
  ### 写后复核
130
132
 
131
- 再次 **`ad campaigns --json`** 或 **`ad groups --json`**,确认 `targetCpa_BidingAmount` / `targetCpaAmount` / `maxCPCAmount` 等与预期一致。
133
+ 再次 **`ad campaigns --json`** 或 **`ad groups --json`**:
134
+ - 优先比对 **`*Display` 字段**(主币种)与预期主币种金额一致;
135
+ - 整数字段 `targetCpa_BidingAmount` / `targetCpaAmount` / `maxCPCAmount` / `budget` 应等于 `主币种 × 100` 后的整数。
132
136
 
133
137
  ### CLI 能力摘要
134
138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-tso-cli",
3
- "version": "1.1.14-beta.6",
3
+ "version": "1.1.14-beta.8",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "keywords": [
6
6
  "ad-account",