siluzan-tso-cli 1.1.30 → 1.1.31-beta.2

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
@@ -43,7 +43,7 @@ HTML 报告模板外部资源:**ECharts** 统一使用 `https://staticpn.siluz
43
43
  在**用户的目标项目根目录**执行(根据用户使用的助手选择 `--ai`):
44
44
 
45
45
  ```bash
46
- npm install -g siluzan-tso-cli
46
+ npm install -g siluzan-tso-cli@beta
47
47
  siluzan-tso init --ai cursor # 写入 Cursor(默认)
48
48
  siluzan-tso init --ai cursor,claude # 同时写入多个平台
49
49
  siluzan-tso init --ai all # 写入所有支持的平台
@@ -51,6 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
51
51
  siluzan-tso init --force # 强制覆盖已存在文件
52
52
  ```
53
53
 
54
+ > **注意**:当前为测试版(1.1.31-beta.2),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
55
 
55
56
  | 助手 | 建议 `--ai` |
56
57
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -2119,6 +2119,61 @@ function validateBaseUrl(raw) {
2119
2119
  }
2120
2120
  return null;
2121
2121
  }
2122
+ function isIdFieldName(key) {
2123
+ if (!key) return false;
2124
+ if (EXACT_ID_FIELD_NAMES.has(key)) return true;
2125
+ if (/Ids$/.test(key)) return true;
2126
+ if (/Id$/.test(key)) return true;
2127
+ return false;
2128
+ }
2129
+ function numberToIdString(n) {
2130
+ if (!Number.isFinite(n)) return String(n);
2131
+ if (Number.isInteger(n)) {
2132
+ return n.toLocaleString("en-US", { useGrouping: false, maximumFractionDigits: 0 });
2133
+ }
2134
+ return String(n);
2135
+ }
2136
+ function scalarToIdString(value) {
2137
+ if (typeof value === "string") return value;
2138
+ if (typeof value === "bigint") return value.toString();
2139
+ if (typeof value === "number") return numberToIdString(value);
2140
+ return String(value);
2141
+ }
2142
+ function normalizeIdFieldValue(value) {
2143
+ if (value === null || value === void 0) return value;
2144
+ if (Array.isArray(value)) {
2145
+ return value.map(
2146
+ (item) => typeof item === "number" || typeof item === "bigint" ? scalarToIdString(item) : stringifyIdsDeep(item)
2147
+ );
2148
+ }
2149
+ if (typeof value === "number" || typeof value === "bigint") {
2150
+ return scalarToIdString(value);
2151
+ }
2152
+ if (typeof value === "string") return value;
2153
+ return stringifyIdsDeep(value);
2154
+ }
2155
+ function stringifyIdsDeep(value) {
2156
+ if (value === null || value === void 0) return value;
2157
+ if (typeof value !== "object") return value;
2158
+ if (Array.isArray(value)) {
2159
+ return value.map((item) => stringifyIdsDeep(item));
2160
+ }
2161
+ const out = {};
2162
+ for (const [key, raw] of Object.entries(value)) {
2163
+ if (raw === void 0) continue;
2164
+ out[key] = isIdFieldName(key) ? normalizeIdFieldValue(raw) : stringifyIdsDeep(raw);
2165
+ }
2166
+ return out;
2167
+ }
2168
+ function jsonParseReviverStringifyIds(key, value) {
2169
+ if (key && isIdFieldName(key) && typeof value === "number" && Number.isFinite(value)) {
2170
+ return numberToIdString(value);
2171
+ }
2172
+ return value;
2173
+ }
2174
+ function parseJsonWithStringIds(text) {
2175
+ return JSON.parse(text, jsonParseReviverStringifyIds);
2176
+ }
2122
2177
  function hasSiluzanAgentCredentials() {
2123
2178
  const apiKey = process.env.SILUZAN_API_KEY?.trim();
2124
2179
  const authToken = process.env.SILUZAN_AUTH_TOKEN?.trim();
@@ -2348,7 +2403,7 @@ async function apiFetch(url, config, options = {}, verbose = false) {
2348
2403
  }
2349
2404
  if (!text.trim()) return null;
2350
2405
  try {
2351
- return JSON.parse(text);
2406
+ return parseJsonWithStringIds(text);
2352
2407
  } catch {
2353
2408
  if (verbose) {
2354
2409
  console.error(` \u26A0\uFE0F \u54CD\u5E94\u975E JSON\uFF0C\u539F\u59CB\u5185\u5BB9\uFF1A${redactSensitive(text).slice(0, 200)}`);
@@ -2378,7 +2433,7 @@ async function apiFetchWithHeaders(url, config, options = {}, verbose = false) {
2378
2433
  data = null;
2379
2434
  } else {
2380
2435
  try {
2381
- data = JSON.parse(text);
2436
+ data = parseJsonWithStringIds(text);
2382
2437
  } catch {
2383
2438
  data = text;
2384
2439
  }
@@ -2809,13 +2864,14 @@ async function writeCliJsonSnapshot(params) {
2809
2864
  }
2810
2865
  const writtenAt = (/* @__PURE__ */ new Date()).toISOString();
2811
2866
  const absFilePath = path4.join(absDir, fileName);
2812
- await fs4.writeFile(absFilePath, `${JSON.stringify(params.payload, null, 2)}
2867
+ const normalizedPayload = stringifyIdsDeep(params.payload);
2868
+ await fs4.writeFile(absFilePath, `${JSON.stringify(normalizedPayload, null, 2)}
2813
2869
  `, "utf8");
2814
2870
  const outlineFileName = snapshotOutlineFileName(fileName);
2815
2871
  if (outlineFileName.toLowerCase() === manifestFile.toLowerCase()) {
2816
2872
  throw new Error(`\u975E\u6CD5\u8F93\u51FA\uFF1A${outlineFileName} \u4E0E\u6E05\u5355\u6587\u4EF6\u540D\u51B2\u7A81`);
2817
2873
  }
2818
- const outlineBody = formatOutlineFileBody(fileName, params.payload);
2874
+ const outlineBody = formatOutlineFileBody(fileName, normalizedPayload);
2819
2875
  await fs4.writeFile(path4.join(absDir, outlineFileName), `${outlineBody}
2820
2876
  `, "utf8");
2821
2877
  const existing = await readCliManifestIfExists(absDir, idSlug || void 0);
@@ -2831,7 +2887,7 @@ async function writeCliJsonSnapshot(params) {
2831
2887
  });
2832
2888
  await fs4.writeFile(
2833
2889
  path4.join(absDir, manifestFile),
2834
- `${JSON.stringify(merged, null, 2)}
2890
+ `${JSON.stringify(stringifyIdsDeep(merged), null, 2)}
2835
2891
  `,
2836
2892
  "utf8"
2837
2893
  );
@@ -3599,7 +3655,7 @@ async function issueApiKeyWithPhoneCode(opts) {
3599
3655
  });
3600
3656
  return apiKey;
3601
3657
  }
3602
- var import_semver, SILUZAN_DIR, CONFIG_FILE, inProcessLockChain, ALLOWED_HOSTNAME_SUFFIXES, DEFAULT_TIMEOUT_MS, MAX_RESPONSE_BYTES, httpsAgent, httpAgent, PERF_PREFIX, ASCII_TABLE_CHARS, CLI_SNAPSHOT_MANIFEST_FILE, SCHEMA_VERSION, FALLBACK_FIELD_GUIDE_REFS, _cliPackage, _resolveCliVersion, _fieldGuideRefs, OUTLINE_AGENT_HINT, TS_LIKE_ARRAY_SAMPLE_MAX, MAX_INVOCATION_CHARS, currentInvocation, MAX_COMMIT_CHARS, cliCommitOverride, WRITE_AUDIT_SCHEMA_VERSION, MUTATING, BEIJING_TZ, AUDIT_LOG_FILENAME_RE, DEFAULT_MAX_FILE_MB, MIN_SEGMENT_BYTES, MAX_SEGMENT_BYTES, DEFAULT_RETENTION_DAYS, MIN_RETENTION_DAYS, MAX_RETENTION_DAYS, PRUNE_THROTTLE_MS, lastPruneAtMs, MAX_BODY_CHARS, MAX_ERROR_CHARS, DEFAULT_FIND_AUDIT_MAX_DAYS, MAX_SNAPSHOT_FILE_BYTES, API_KEY_SERVICE_VALUES;
3658
+ var import_semver, SILUZAN_DIR, CONFIG_FILE, inProcessLockChain, ALLOWED_HOSTNAME_SUFFIXES, EXACT_ID_FIELD_NAMES, DEFAULT_TIMEOUT_MS, MAX_RESPONSE_BYTES, httpsAgent, httpAgent, PERF_PREFIX, ASCII_TABLE_CHARS, CLI_SNAPSHOT_MANIFEST_FILE, SCHEMA_VERSION, FALLBACK_FIELD_GUIDE_REFS, _cliPackage, _resolveCliVersion, _fieldGuideRefs, OUTLINE_AGENT_HINT, TS_LIKE_ARRAY_SAMPLE_MAX, MAX_INVOCATION_CHARS, currentInvocation, MAX_COMMIT_CHARS, cliCommitOverride, WRITE_AUDIT_SCHEMA_VERSION, MUTATING, BEIJING_TZ, AUDIT_LOG_FILENAME_RE, DEFAULT_MAX_FILE_MB, MIN_SEGMENT_BYTES, MAX_SEGMENT_BYTES, DEFAULT_RETENTION_DAYS, MIN_RETENTION_DAYS, MAX_RETENTION_DAYS, PRUNE_THROTTLE_MS, lastPruneAtMs, MAX_BODY_CHARS, MAX_ERROR_CHARS, DEFAULT_FIND_AUDIT_MAX_DAYS, MAX_SNAPSHOT_FILE_BYTES, API_KEY_SERVICE_VALUES;
3603
3659
  var init_dist = __esm({
3604
3660
  "../common/dist/index.js"() {
3605
3661
  "use strict";
@@ -3613,6 +3669,38 @@ var init_dist = __esm({
3613
3669
  /** Google / TikTok / Facebook 等媒体网关域名(TSO 专用,CSO 不会主动产生但兼容写入) */
3614
3670
  "mysiluzan.com"
3615
3671
  ];
3672
+ EXACT_ID_FIELD_NAMES = /* @__PURE__ */ new Set([
3673
+ "id",
3674
+ "entityId",
3675
+ "mediaCustomerId",
3676
+ "mediaAccountId",
3677
+ "mediaAccountGroupId",
3678
+ "loginCustomerId",
3679
+ "customerId",
3680
+ "accountId",
3681
+ "ownerAdvertiserId",
3682
+ "advertiserId",
3683
+ "agencyClientId",
3684
+ "externalMediaAccountTokenId",
3685
+ "shortId",
3686
+ "websiteDiagnoseId",
3687
+ "invitationId",
3688
+ "ruleId",
3689
+ "bcId",
3690
+ "bmId",
3691
+ "tradeNo",
3692
+ "billNo",
3693
+ "payNo",
3694
+ "checkingNo",
3695
+ "rechargeNo",
3696
+ "orderNo",
3697
+ "magKey",
3698
+ "managedByStewardId",
3699
+ "relyCustomerId",
3700
+ "createdBy",
3701
+ "lastChangedBy",
3702
+ "userId"
3703
+ ]);
3616
3704
  DEFAULT_TIMEOUT_MS = 10 * 60 * 1e3;
3617
3705
  MAX_RESPONSE_BYTES = 50 * 1024 * 1024;
3618
3706
  httpsAgent = new https.Agent({
@@ -3686,7 +3774,7 @@ var DEFAULT_API_BASE;
3686
3774
  var init_defaults = __esm({
3687
3775
  "src/config/defaults.ts"() {
3688
3776
  "use strict";
3689
- DEFAULT_API_BASE = "https://tso-api.siluzan.com";
3777
+ DEFAULT_API_BASE = "https://tso-api-ci.siluzan.com";
3690
3778
  }
3691
3779
  });
3692
3780
 
@@ -5231,12 +5319,13 @@ async function writeGoogleAnalysisSnapshot(params) {
5231
5319
  params.section,
5232
5320
  params.payload
5233
5321
  );
5234
- const body = JSON.stringify(wrapped, null, 2);
5322
+ const normalizedWrapped = stringifyIdsDeep(wrapped);
5323
+ const body = JSON.stringify(normalizedWrapped, null, 2);
5235
5324
  await fs7.writeFile(path11.join(absDir, fileName), `${body}
5236
5325
  `, "utf8");
5237
5326
  const outlineFileName = snapshotOutlineFileName(fileName);
5238
5327
  const outlineExtra = buildOutlineHints(params.section);
5239
- const outlineBody = formatOutlineFileBody(fileName, wrapped, outlineExtra);
5328
+ const outlineBody = formatOutlineFileBody(fileName, normalizedWrapped, outlineExtra);
5240
5329
  await fs7.writeFile(path11.join(absDir, outlineFileName), `${outlineBody}
5241
5330
  `, "utf8");
5242
5331
  const existing = await readManifestIfExists(absDir, accountSlug || void 0);
@@ -5255,7 +5344,7 @@ async function writeGoogleAnalysisSnapshot(params) {
5255
5344
  const manifestFile = googleAnalysisManifestFile(accountSlug || void 0);
5256
5345
  await fs7.writeFile(
5257
5346
  path11.join(absDir, manifestFile),
5258
- `${JSON.stringify(merged, null, 2)}
5347
+ `${JSON.stringify(stringifyIdsDeep(merged), null, 2)}
5259
5348
  `,
5260
5349
  "utf8"
5261
5350
  );
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.30",
4
- "publishedAt": 1782461594853
3
+ "version": "1.1.31-beta.2",
4
+ "publishedAt": 1782703014094
5
5
  }
@@ -280,7 +280,7 @@ siluzan-tso account-history --start 2026-03-01 --end 2026-03-31 --json-out ./sna
280
280
  | 状态 | 含义 | 下一步操作 |
281
281
  | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
282
282
  | `Pending` | 审核中 | 等待,可反复运行此命令轮询;审核周期因媒体而异 |
283
- | `Approved` | 审核通过 | 运行 `list-accounts -m <媒体>` 确认账户已出现;引导用户充值激活(`config show` 取 `webUrl`,按 `finance.md` 打开对应媒体充值页;例如 Google 为 `https://www.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google`;Kwai、Yandex 当前没有对应充值界面) |
283
+ | `Approved` | 审核通过 | 运行 `list-accounts -m <媒体>` 确认账户已出现;引导用户充值激活(`config show` 取 `webUrl`,按 `finance.md` 打开对应媒体充值页;例如 Google 为 `https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google`;Kwai、Yandex 当前没有对应充值界面) |
284
284
  | `Rejected` | 被拒 | 查看 `--json-out` 落盘中的 `reason` 字段了解拒绝原因;修改资料后重新提交;若原因不明,引导用户联系丝路赞客服 |
285
285
 
286
286
  ---
@@ -854,7 +854,7 @@ siluzan-tso account email-deauth -c <mediaCustomerId> --invitation-id <id> --res
854
854
 
855
855
  | 功能 | 媒体 | 网页路径 |
856
856
  | --------------------------------------- | ------ | ------------------------------------------------- |
857
- | **账户激活**(邀请他人激活 / 充值激活) | Google | `https://www.siluzan.com/v3/foreign_trade/tso/manageAccounts` |
857
+ | **账户激活**(邀请他人激活 / 充值激活) | Google | `https://www-ci.siluzan.com/v3/foreign_trade/tso/manageAccounts` |
858
858
 
859
859
  **Agent 建议话术**:
860
860
 
@@ -863,5 +863,5 @@ siluzan-tso account email-deauth -c <mediaCustomerId> --invitation-id <id> --res
863
863
  siluzan-tso config show # 查看 webUrl 字段
864
864
 
865
865
  # 账户激活(Google)→ 引导至账户管理页
866
- # https://www.siluzan.com/v3/foreign_trade/tso/manageAccounts
866
+ # https://www-ci.siluzan.com/v3/foreign_trade/tso/manageAccounts
867
867
  ```
@@ -117,7 +117,7 @@ siluzan-tso config show
117
117
 
118
118
  ### 充值页链接(按媒体 × 类型)
119
119
 
120
- 链接模式:`https://www.siluzan.com/v3/foreign_trade/tso/recharge/<page>?mediaType=<mediaType>`;丝路赞钱包:`https://www.siluzan.com/v3/foreign_trade/tso/recharge/siluzanWallet`(无媒体参数)。
120
+ 链接模式:`https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/<page>?mediaType=<mediaType>`;丝路赞钱包:`https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/siluzanWallet`(无媒体参数)。
121
121
 
122
122
  | 充值类型 | `<page>` | 支持媒体(`mediaType` 参数) |
123
123
  | ------------------------- | --------------------- | ------------------------------------------- |
@@ -1,6 +1,6 @@
1
1
  # 各媒体开户
2
2
 
3
- > 网页链接:`https://www.siluzan.com/v3/foreign_trade/tso/accountOpeningHistory?tso=%2Fv3umijs%2Ftso%2FaccountOpeningHistory`
3
+ > 网页链接:`https://www-ci.siluzan.com/v3/foreign_trade/tso/accountOpeningHistory?tso=%2Fv3umijs%2Ftso%2FaccountOpeningHistory`
4
4
  > 多命令串联见 `references/core/workflows.md` § 流程一。
5
5
 
6
6
  ## 首次响应硬规范(必读)
@@ -60,7 +60,7 @@ siluzan-tso open-account google-wizard
60
60
 
61
61
  ```bash
62
62
  siluzan-tso account-history -m Google
63
- # 审核通过后:config show → https://www.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google
63
+ # 审核通过后:config show → https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google
64
64
  ```
65
65
 
66
66
  ---
@@ -1,6 +1,6 @@
1
1
  # rag:知识库检索(TSO 广告投放辅助)
2
2
 
3
- 知识库管理页面在 https://www.siluzan.com/knowledge-base/
3
+ 知识库管理页面在 https://www-ci.siluzan.com/knowledge-base/
4
4
 
5
5
  为 **广告投放、账户分析、拓词、诊断报告** 等 TSO 业务提供**企业已入库**的产品、行业、客户背景事实依据。
6
6
 
@@ -192,9 +192,9 @@ siluzan-tso report push receive-emails -m Google [--json-out ./snap]
192
192
 
193
193
  | 媒体 | 报告类型 | URL 模板 |
194
194
  | ------ | ---------------- | ----------------------------------------------------------- |
195
- | Google | 日报(Daily) | `https://www.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
196
- | Google | 小时报(Hourly) | `https://www.siluzan.com/media-report/hour/{entityId}?culture=zh-CN` |
197
- | TikTok | 日报 | `https://www.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
195
+ | Google | 日报(Daily) | `https://www-ci.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
196
+ | Google | 小时报(Hourly) | `https://www-ci.siluzan.com/media-report/hour/{entityId}?culture=zh-CN` |
197
+ | TikTok | 日报 | `https://www-ci.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
198
198
 
199
199
  `entityId` 来自 `siluzan-tso report list --json-out ./snap` 中每条记录的 `entityId` 字段。
200
200
 
@@ -207,8 +207,8 @@ siluzan-tso report list -m Google --json-out ./snap
207
207
 
208
208
  # 第二步:查看 webUrl
209
209
  siluzan-tso config show
210
- # webUrl: https://www.siluzan.com
210
+ # webUrl: https://www-ci.siluzan.com
211
211
 
212
212
  # 第三步:拼接链接(Google 日报)
213
- # https://www.siluzan.com/media-report/publish/rpt_abc123?culture=zh-CN
213
+ # https://www-ci.siluzan.com/media-report/publish/rpt_abc123?culture=zh-CN
214
214
  ```
@@ -10,7 +10,7 @@
10
10
  ## 安装 CLI
11
11
 
12
12
  ```bash
13
- npm install -g siluzan-tso-cli
13
+ npm install -g siluzan-tso-cli@beta
14
14
  ```
15
15
 
16
16
  ---
@@ -64,7 +64,7 @@ siluzan-tso config set --api-key <Key> # 或 config 直接写入
64
64
  siluzan-tso config set --token <Token> # 备用:设置 JWT Token
65
65
  ```
66
66
 
67
- API Key 获取入口:`https://www.siluzan.com/v3/foreign_trade/settings/apiKeyManagement`
67
+ API Key 获取入口:`https://www-ci.siluzan.com/v3/foreign_trade/settings/apiKeyManagement`
68
68
 
69
69
  ```bash
70
70
  # 第 1 步:让用户报出手机号后,立刻发码(命令立即返回,不会等待输入)
@@ -129,9 +129,9 @@ siluzan-tso config show
129
129
 
130
130
  ```
131
131
  构建环境 : production
132
- apiBaseUrl : https://tso-api.siluzan.com
133
- googleApiUrl : https://googleapi.mysiluzan.com
134
- webUrl : https://www.siluzan.com
132
+ apiBaseUrl : https://tso-api-ci.siluzan.com
133
+ googleApiUrl : https://googleapi-ci.mysiluzan.com
134
+ webUrl : https://www-ci.siluzan.com
135
135
  apiKey : abcd****1234
136
136
  ```
137
137
 
@@ -6,7 +6,7 @@
6
6
  siluzan-tso config show # 取 webUrl
7
7
  ```
8
8
 
9
- 首页地址:`https://www.siluzan.com/v3/foreign_trade/tso/home`
9
+ 首页地址:`https://www-ci.siluzan.com/v3/foreign_trade/tso/home`
10
10
 
11
11
  ---
12
12
 
@@ -25,7 +25,7 @@ siluzan-tso config show # 取 webUrl
25
25
 
26
26
  ## 推荐话术
27
27
 
28
- 1. **「和首页一样的总览」** → 打开 `https://www.siluzan.com/v3/foreign_trade/tso/home`。
28
+ 1. **「和首页一样的总览」** → 打开 `https://www-ci.siluzan.com/v3/foreign_trade/tso/home`。
29
29
  2. **「某个 Google 账户昨天花了多少」** → `list-accounts -m Google` + `stats -m Google -a <id>`。
30
30
  3. **「有待充值账户」** → 说明聚合数据在首页;CLI 可 `list-accounts` + `balance` 逐户排查,或引导充值页。
31
31
 
@@ -2,7 +2,7 @@
2
2
  <html lang="zh-CN">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
6
  <title>Google Ads 账户诊断报告</title>
7
7
  <style>
8
8
  * {
@@ -1909,8 +1909,44 @@
1909
1909
  }
1910
1910
 
1911
1911
  @media (max-width: 768px) {
1912
+ html {
1913
+ -webkit-text-size-adjust: 100%;
1914
+ text-size-adjust: 100%;
1915
+ }
1916
+
1917
+ body {
1918
+ overflow-x: clip;
1919
+ -webkit-tap-highlight-color: transparent;
1920
+ }
1921
+
1922
+ #report-root {
1923
+ padding: max(8px, env(safe-area-inset-left, 0px))
1924
+ max(8px, env(safe-area-inset-right, 0px))
1925
+ max(28px, env(safe-area-inset-bottom, 0px));
1926
+ max-width: 100%;
1927
+ }
1928
+
1912
1929
  .report-header {
1913
- padding: 28px 24px;
1930
+ padding: 18px 16px;
1931
+ border-radius: 14px;
1932
+ }
1933
+
1934
+ .report-title {
1935
+ font-size: clamp(1.125rem, 5.2vw, 1.375rem);
1936
+ line-height: 1.35;
1937
+ word-break: break-word;
1938
+ }
1939
+
1940
+ .report-meta {
1941
+ flex-direction: column;
1942
+ align-items: flex-start;
1943
+ gap: 8px;
1944
+ font-size: 13px;
1945
+ }
1946
+
1947
+ .report-submeta {
1948
+ font-size: 13px;
1949
+ line-height: 1.55;
1914
1950
  }
1915
1951
 
1916
1952
  .header-top {
@@ -1918,18 +1954,57 @@
1918
1954
  align-items: stretch;
1919
1955
  }
1920
1956
 
1957
+ .diagnosis-navigation {
1958
+ top: env(safe-area-inset-top, 0px);
1959
+ margin-top: 8px;
1960
+ margin-inline: -2px;
1961
+ padding: 12px 12px 10px;
1962
+ border-radius: 14px;
1963
+ }
1964
+
1965
+ .diagnosis-navigation .nav-title {
1966
+ font-size: 14px;
1967
+ margin-bottom: 10px;
1968
+ }
1969
+
1970
+ .diagnosis-navigation .nav-tags {
1971
+ flex-wrap: nowrap;
1972
+ overflow-x: auto;
1973
+ overflow-y: hidden;
1974
+ -webkit-overflow-scrolling: touch;
1975
+ scroll-snap-type: x mandatory;
1976
+ scroll-padding-inline: 8px;
1977
+ gap: 8px;
1978
+ padding-bottom: 4px;
1979
+ margin-inline: -4px;
1980
+ padding-inline: 4px;
1981
+ }
1982
+
1983
+ .diagnosis-navigation .nav-tag {
1984
+ flex: 0 0 auto;
1985
+ scroll-snap-align: start;
1986
+ min-height: 44px;
1987
+ padding: 10px 14px;
1988
+ font-size: 13px;
1989
+ white-space: nowrap;
1990
+ }
1991
+
1921
1992
  .report-main {
1922
- margin-top: 24px;
1923
- gap: 16px;
1993
+ margin-top: 16px;
1994
+ gap: 14px;
1924
1995
  }
1925
1996
 
1926
1997
  .section-header {
1927
- padding: 15px 15px 10px;
1998
+ flex-direction: column;
1999
+ align-items: flex-start;
2000
+ padding: 14px 16px;
2001
+ scroll-margin-top: calc(env(safe-area-inset-top, 0px) + 92px);
1928
2002
  }
1929
2003
 
1930
2004
  .section-title {
1931
- font-size: 22px;
2005
+ font-size: clamp(1.05rem, 4.8vw, 1.25rem);
1932
2006
  gap: 10px;
2007
+ flex-wrap: wrap;
1933
2008
  }
1934
2009
 
1935
2010
  .section-title::after {
@@ -1937,7 +2012,7 @@
1937
2012
  }
1938
2013
 
1939
2014
  .section-subtitle {
1940
- font-size: 16px;
2015
+ font-size: 15px;
1941
2016
  gap: 10px;
1942
2017
  }
1943
2018
 
@@ -1951,6 +2026,41 @@
1951
2026
  font-size: 14px;
1952
2027
  }
1953
2028
 
2029
+ .content-wrapper[data-section-id] {
2030
+ padding: 12px;
2031
+ margin-bottom: 18px;
2032
+ }
2033
+
2034
+ .table-block {
2035
+ position: relative;
2036
+ margin-inline: -4px;
2037
+ border-radius: 10px;
2038
+ overflow-x: auto;
2039
+ overscroll-behavior-x: contain;
2040
+ -webkit-overflow-scrolling: touch;
2041
+ }
2042
+
2043
+ .kpi-section .table-block {
2044
+ overflow-x: visible;
2045
+ margin-inline: 0;
2046
+ }
2047
+
2048
+ .table-block:not(.kpi-section .table-block) .data-table {
2049
+ min-width: 520px;
2050
+ }
2051
+
2052
+ .chart-card canvas,
2053
+ .chart-container canvas {
2054
+ max-width: 100%;
2055
+ }
2056
+
2057
+ .insights-container,
2058
+ .targeting-layout,
2059
+ .ad-creative-section .rules-content,
2060
+ .gold-rules-info .rules-grid {
2061
+ grid-template-columns: 1fr !important;
2062
+ }
2063
+
1954
2064
  .content-wrapper[data-section-id] .info-table .table-row {
1955
2065
  flex-direction: column;
1956
2066
  }
@@ -2002,6 +2112,7 @@
2002
2112
  font-size: 13px;
2003
2113
  }
2004
2114
  }
2115
+
2005
2116
  </style>
2006
2117
  <script src="https://staticpn.siluzan.com/assets/slz/homeCDN/chart.umd.min.js"></script>
2007
2118
  </head>
@@ -2,7 +2,7 @@
2
2
  <html lang="zh-CN">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
6
  <title>Meta / Facebook 周期分析报告</title>
7
7
 
8
8
  <script src="https://staticpn.siluzan.com/assets/slz/homeCDN/echarts.js"></script>
@@ -298,6 +298,132 @@
298
298
  font-size: 0.9rem;
299
299
  padding: 12px 0;
300
300
  }
301
+
302
+
303
+
304
+ /* 移动端原生适配(≤768px,Meta 周期报告) */
305
+ @supports (padding: env(safe-area-inset-bottom)) {
306
+ body {
307
+ padding-left: env(safe-area-inset-left, 0);
308
+ padding-right: env(safe-area-inset-right, 0);
309
+ padding-bottom: env(safe-area-inset-bottom, 0);
310
+ }
311
+ }
312
+
313
+ @media (max-width: 768px) {
314
+ html {
315
+ -webkit-text-size-adjust: 100%;
316
+ text-size-adjust: 100%;
317
+ }
318
+
319
+ body {
320
+ overflow-x: clip;
321
+ -webkit-tap-highlight-color: transparent;
322
+ }
323
+
324
+ .wrap {
325
+ padding: max(12px, env(safe-area-inset-left, 0px))
326
+ max(12px, env(safe-area-inset-right, 0px))
327
+ max(40px, env(safe-area-inset-bottom, 0px));
328
+ }
329
+
330
+ .hero {
331
+ padding: 18px 16px;
332
+ border-radius: 14px;
333
+ }
334
+
335
+ .hero h1 {
336
+ font-size: clamp(1.1rem, 5vw, 1.35rem);
337
+ line-height: 1.4;
338
+ word-break: break-word;
339
+ }
340
+
341
+ .hero .sub {
342
+ font-size: 0.82rem;
343
+ line-height: 1.55;
344
+ }
345
+
346
+ .kpi-grid {
347
+ grid-template-columns: repeat(2, minmax(0, 1fr));
348
+ gap: 10px;
349
+ }
350
+
351
+ .kpi {
352
+ padding: 12px 10px;
353
+ border-radius: 12px;
354
+ }
355
+
356
+ .kpi .v {
357
+ font-size: clamp(1.05rem, 4.5vw, 1.25rem);
358
+ }
359
+
360
+ h2 {
361
+ font-size: clamp(1rem, 4.2vw, 1.15rem);
362
+ }
363
+
364
+ .card {
365
+ padding: 14px 12px;
366
+ border-radius: 12px;
367
+ }
368
+
369
+ .chart-box {
370
+ height: clamp(220px, 56vw, 260px);
371
+ }
372
+
373
+ .lifecycle {
374
+ flex-direction: column;
375
+ gap: 10px;
376
+ }
377
+
378
+ .phase {
379
+ min-width: 100%;
380
+ }
381
+
382
+ .four-q,
383
+ .ab-grid,
384
+ .checklist {
385
+ grid-template-columns: 1fr !important;
386
+ }
387
+
388
+ .card:has(table) {
389
+ overflow-x: auto;
390
+ overscroll-behavior-x: contain;
391
+ -webkit-overflow-scrolling: touch;
392
+ }
393
+
394
+ .card:has(table)::before {
395
+ display: block;
396
+ text-align: center;
397
+ font-size: 12px;
398
+ color: var(--muted);
399
+ padding: 0 0 8px;
400
+ content: "左右滑动查看表格";
401
+ }
402
+
403
+ .card table {
404
+ min-width: 520px;
405
+ font-size: 0.82rem;
406
+ }
407
+
408
+ th,
409
+ td {
410
+ padding: 8px 10px;
411
+ }
412
+ }
413
+
414
+ @media (min-width: 769px) {
415
+ .card:has(table)::before {
416
+ display: none;
417
+ content: none;
418
+ }
419
+ }
420
+
421
+ @media print {
422
+ .card:has(table)::before {
423
+ display: none !important;
424
+ content: none !important;
425
+ }
426
+ }
301
427
  </style>
302
428
  </head>
303
429
  <body>
@@ -10,7 +10,7 @@
10
10
  <html lang="zh-CN">
11
11
  <head>
12
12
  <meta charset="UTF-8" />
13
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
14
14
  <title>广告数据报告 — 学术风格版式参考</title>
15
15
  <link rel="preconnect" href="https://fonts.googleapis.com" />
16
16
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -56,19 +56,83 @@
56
56
  display: none !important;
57
57
  }
58
58
  }
59
+
60
+
61
+
62
+ /* 移动端原生适配(≤768px,内联) */
63
+ @supports (padding: env(safe-area-inset-bottom)) {
64
+ body {
65
+ padding-left: env(safe-area-inset-left, 0);
66
+ padding-right: env(safe-area-inset-right, 0);
67
+ padding-bottom: env(safe-area-inset-bottom, 0);
68
+ }
69
+ }
70
+
71
+ @media (max-width: 768px) {
72
+ html {
73
+ -webkit-text-size-adjust: 100%;
74
+ text-size-adjust: 100%;
75
+ }
76
+
77
+ body {
78
+ overflow-x: clip;
79
+ -webkit-tap-highlight-color: transparent;
80
+ }
81
+
82
+ main {
83
+ padding-left: max(12px, env(safe-area-inset-left, 0px));
84
+ padding-right: max(12px, env(safe-area-inset-right, 0px));
85
+ }
86
+
87
+ .mobile-scroll-hint {
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ gap: 6px;
92
+ font-size: 12px;
93
+ color: #94a3b8;
94
+ padding: 8px 4px 4px;
95
+ }
96
+
97
+ .overflow-x-auto {
98
+ margin-inline: -4px;
99
+ padding-inline: 4px 12px;
100
+ overscroll-behavior-x: contain;
101
+ -webkit-overflow-scrolling: touch;
102
+ }
103
+
104
+ [id$="Chart"],
105
+ .h-72,
106
+ .h-64 {
107
+ height: clamp(220px, 58vw, 288px) !important;
108
+ min-height: 220px;
109
+ }
110
+ }
111
+
112
+ @media (min-width: 769px) {
113
+ .mobile-scroll-hint {
114
+ display: none !important;
115
+ }
116
+ }
117
+
118
+ @media print {
119
+ .mobile-scroll-hint {
120
+ display: none !important;
121
+ }
122
+ }
59
123
  </style>
60
124
  </head>
61
125
  <body class="min-h-screen bg-stone-200 font-serif text-stone-900 antialiased leading-relaxed">
62
126
  <main
63
- class="mx-auto my-6 max-w-3xl bg-white px-6 py-10 shadow-sm ring-1 ring-stone-300 sm:px-10 sm:py-12"
127
+ class="mx-auto my-4 max-w-3xl bg-white px-4 py-8 shadow-sm ring-1 ring-stone-300 sm:my-6 sm:px-10 sm:py-12"
64
128
  >
65
- <header class="mb-10 border-b-2 border-stone-800 pb-6">
129
+ <header class="mb-8 border-b-2 border-stone-800 pb-5 sm:mb-10 sm:pb-6">
66
130
  <div class="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
67
131
  <div>
68
132
  <p class="font-sans text-[11px] font-medium uppercase tracking-[0.2em] text-stone-500">
69
133
  Technical Report · Siluzan
70
134
  </p>
71
- <h1 class="mt-2 text-2xl font-semibold tracking-tight text-stone-900 sm:text-3xl">
135
+ <h1 class="mt-2 text-xl font-semibold tracking-tight text-stone-900 sm:text-3xl">
72
136
  <i class="fa-solid fa-book-open mr-2 text-stone-600" aria-hidden="true"></i>
73
137
  数据报告标题
74
138
  </h1>
@@ -107,7 +171,7 @@
107
171
  总览类指标(消耗、展示、点击、转化及派生率);环比以符号与脚注形式呈现,避免过度装饰。
108
172
  </p>
109
173
 
110
- <div class="grid grid-cols-2 gap-3 font-sans lg:grid-cols-4">
174
+ <div class="grid grid-cols-1 gap-3 font-sans sm:grid-cols-2 lg:grid-cols-4">
111
175
  <article class="border border-stone-400 bg-stone-50/80 p-4">
112
176
  <div
113
177
  class="flex items-center justify-between text-xs font-medium uppercase tracking-wide text-stone-500"
@@ -296,6 +360,7 @@
296
360
  明细数据表
297
361
  </h2>
298
362
  <div class="overflow-x-auto border border-stone-800">
363
+ <p class="mobile-scroll-hint no-print font-sans">← 左右滑动查看更多列 →</p>
299
364
  <table class="min-w-[640px] w-full border-collapse text-left font-sans text-sm">
300
365
  <thead>
301
366
  <tr class="border-b border-stone-800 bg-stone-200">
@@ -33,7 +33,7 @@
33
33
  <html lang="zh-CN">
34
34
  <head>
35
35
  <meta charset="UTF-8" />
36
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
36
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
37
37
  <title>广告数据报告 — 商务风格版式参考</title>
38
38
  <!-- Tailwind CSS(Play CDN):布局与工具类 -->
39
39
  <script src="https://cdn.tailwindcss.com"></script>
@@ -87,33 +87,96 @@
87
87
  display: none !important;
88
88
  }
89
89
  }
90
+
91
+
92
+
93
+ /* 移动端原生适配(≤768px,内联) */
94
+ @supports (padding: env(safe-area-inset-bottom)) {
95
+ body {
96
+ padding-left: env(safe-area-inset-left, 0);
97
+ padding-right: env(safe-area-inset-right, 0);
98
+ padding-bottom: env(safe-area-inset-bottom, 0);
99
+ }
100
+ }
101
+
102
+ @media (max-width: 768px) {
103
+ html {
104
+ -webkit-text-size-adjust: 100%;
105
+ text-size-adjust: 100%;
106
+ }
107
+
108
+ body {
109
+ overflow-x: clip;
110
+ -webkit-tap-highlight-color: transparent;
111
+ }
112
+
113
+ main {
114
+ padding-left: max(12px, env(safe-area-inset-left, 0px));
115
+ padding-right: max(12px, env(safe-area-inset-right, 0px));
116
+ }
117
+
118
+ .mobile-scroll-hint {
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ gap: 6px;
123
+ font-size: 12px;
124
+ color: #94a3b8;
125
+ padding: 8px 4px 4px;
126
+ }
127
+
128
+ .overflow-x-auto {
129
+ margin-inline: -4px;
130
+ padding-inline: 4px 12px;
131
+ overscroll-behavior-x: contain;
132
+ -webkit-overflow-scrolling: touch;
133
+ }
134
+
135
+ [id$="Chart"],
136
+ .h-72,
137
+ .h-64 {
138
+ height: clamp(220px, 58vw, 288px) !important;
139
+ min-height: 220px;
140
+ }
141
+ }
142
+
143
+ @media (min-width: 769px) {
144
+ .mobile-scroll-hint {
145
+ display: none !important;
146
+ }
147
+ }
148
+
149
+ @media print {
150
+ .mobile-scroll-hint {
151
+ display: none !important;
152
+ }
153
+ }
90
154
  </style>
91
155
  </head>
92
156
  <body class="min-h-screen bg-slate-50 text-slate-800 antialiased">
93
- <main class="mx-auto max-w-5xl px-4 py-8 sm:px-6 lg:px-8">
157
+ <main class="mx-auto max-w-5xl px-3 py-6 sm:px-6 sm:py-8">
94
158
  <!-- ========== 组件:报告页眉(对应 md 顶部「统计区间 / 账户」) ========== -->
95
- <header class="mb-10 border-b-2 border-brand-600 pb-6">
96
- <div class="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
159
+ <header class="mb-8 border-b-2 border-brand-600 pb-5 sm:mb-10 sm:pb-6">
160
+ <div class="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
97
161
  <div>
98
162
  <p class="text-xs font-medium uppercase tracking-wider text-slate-500">
99
163
  Siluzan · 投放分析
100
164
  </p>
101
- <h1 class="mt-1 text-2xl font-bold tracking-tight text-brand-700 sm:text-3xl">
165
+ <h1 class="mt-1 text-xl font-bold tracking-tight text-brand-700 sm:text-3xl">
102
166
  <i class="fa-solid fa-chart-line mr-2 text-brand-600" aria-hidden="true"></i>
103
167
  数据报告标题
104
168
  </h1>
105
169
  </div>
106
- <div class="flex flex-wrap gap-2 text-sm text-slate-600">
170
+ <div class="flex flex-col gap-2 text-sm text-slate-600 sm:flex-row sm:flex-wrap sm:gap-2">
107
171
  <span
108
- class="inline-flex items-center rounded-full bg-white px-3 py-1 shadow-sm ring-1 ring-slate-200"
172
+ class="inline-flex min-h-[44px] w-full items-center rounded-xl bg-white px-3 py-2 shadow-sm ring-1 ring-slate-200 sm:w-auto sm:rounded-full sm:py-1"
109
173
  >
110
174
  <i class="fa-regular fa-building mr-2 text-slate-400" aria-hidden="true"></i>
111
175
  账户:<strong id="accountName" class="font-semibold text-slate-800">示例账户</strong>
112
176
  </span>
113
177
  <span
114
- class="inline-flex items-center rounded-full bg-white px-3 py-1 shadow-sm ring-1 ring-slate-200"
178
+ class="inline-flex min-h-[44px] w-full items-center rounded-xl bg-white px-3 py-2 shadow-sm ring-1 ring-slate-200 sm:w-auto sm:rounded-full sm:py-1"
115
179
  >
116
- <i class="fa-regular fa-calendar mr-2 text-slate-400" aria-hidden="true"></i>
117
180
  区间:<strong id="reportPeriod" class="font-semibold text-slate-800"
118
181
  >2026-03-01 ~ 2026-03-07</strong
119
182
  >
@@ -149,7 +212,7 @@
149
212
  适用于总览接口:消耗、展示、点击、转化、CTR、CPC、CPA 等;环比用徽章区分涨跌。
150
213
  </p>
151
214
 
152
- <div class="grid grid-cols-2 gap-3 lg:grid-cols-4">
215
+ <div class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
153
216
  <article class="rounded-xl border border-slate-200 bg-white p-4 shadow-sm">
154
217
  <div class="flex items-center justify-between text-slate-500">
155
218
  <span class="text-xs font-medium">消耗</span>
@@ -227,7 +290,8 @@
227
290
  >
228
291
  漏斗式概览(表格 + 序号)
229
292
  </h2>
230
- <div class="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm">
293
+ <div class="overflow-x-auto rounded-xl border border-slate-200 bg-white shadow-sm">
294
+ <p class="mobile-scroll-hint no-print">← 左右滑动查看更多列 →</p>
231
295
  <table class="min-w-full divide-y divide-slate-200 text-sm">
232
296
  <thead class="bg-slate-50">
233
297
  <tr>
@@ -368,6 +432,7 @@
368
432
  明细表(广告结构 / 关键词)
369
433
  </h2>
370
434
  <div class="overflow-x-auto rounded-xl border border-slate-200 bg-white shadow-sm">
435
+ <p class="mobile-scroll-hint no-print">← 左右滑动查看更多列 →</p>
371
436
  <table class="min-w-[640px] w-full divide-y divide-slate-200 text-left text-sm">
372
437
  <thead class="sticky top-0 z-10 bg-slate-100 text-slate-700">
373
438
  <tr>
@@ -8,7 +8,7 @@
8
8
  <html lang="zh-CN">
9
9
  <head>
10
10
  <meta charset="UTF-8" />
11
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
12
12
  <title>网站诊断报告</title>
13
13
  <script>
14
14
  (function () {
@@ -1015,55 +1015,157 @@
1015
1015
  }
1016
1016
  }
1017
1017
 
1018
- @media (max-width: 768px) {
1019
- .loading-speed-charts {
1020
- flex-direction: column;
1021
- align-items: center;
1018
+
1019
+ @media print {
1020
+ body {
1021
+ background: var(--surface);
1022
1022
  }
1023
1023
 
1024
- .longterm-cards {
1025
- grid-template-columns: 1fr;
1024
+ .report-container {
1025
+ padding: 0;
1026
+ background: var(--surface);
1026
1027
  }
1027
1028
 
1028
- .main-title {
1029
- font-size: 24px;
1029
+ .report-content {
1030
+ box-shadow: none;
1030
1031
  }
1031
1032
 
1032
- .header-title-wrapper {
1033
- flex-direction: column;
1034
- align-items: flex-start;
1035
- gap: 12px;
1033
+ .btn-theme {
1034
+ display: none;
1036
1035
  }
1037
1036
 
1038
- .module-items-grid {
1039
- grid-template-columns: 1fr !important;
1037
+ .report-section {
1038
+ break-inside: avoid;
1040
1039
  }
1040
+ }
1041
1041
 
1042
- .priority-items {
1043
- grid-template-columns: 1fr !important;
1042
+
1043
+
1044
+ /* 移动端原生适配(≤768px,网站诊断) */
1045
+ @supports (padding: env(safe-area-inset-bottom)) {
1046
+ body {
1047
+ padding-left: env(safe-area-inset-left, 0);
1048
+ padding-right: env(safe-area-inset-right, 0);
1049
+ padding-bottom: env(safe-area-inset-bottom, 0);
1044
1050
  }
1045
1051
  }
1046
1052
 
1047
- @media print {
1053
+ @media (max-width: 768px) {
1054
+ html {
1055
+ -webkit-text-size-adjust: 100%;
1056
+ text-size-adjust: 100%;
1057
+ }
1058
+
1048
1059
  body {
1049
- background: var(--surface);
1060
+ overflow-x: clip;
1061
+ -webkit-tap-highlight-color: transparent;
1050
1062
  }
1051
1063
 
1052
1064
  .report-container {
1053
- padding: 0;
1054
- background: var(--surface);
1065
+ padding: max(8px, env(safe-area-inset-left, 0px))
1066
+ max(8px, env(safe-area-inset-right, 0px))
1067
+ max(24px, env(safe-area-inset-bottom, 0px));
1055
1068
  }
1056
1069
 
1057
1070
  .report-content {
1071
+ padding: 16px 14px;
1072
+ border-radius: 0;
1058
1073
  box-shadow: none;
1059
1074
  }
1060
1075
 
1076
+ .report-header {
1077
+ margin-bottom: 20px;
1078
+ padding-bottom: 16px;
1079
+ }
1080
+
1081
+ .main-title {
1082
+ font-size: clamp(1.125rem, 5vw, 1.375rem);
1083
+ line-height: 1.35;
1084
+ }
1085
+
1086
+ .header-title-wrapper {
1087
+ flex-direction: column;
1088
+ align-items: stretch;
1089
+ gap: 12px;
1090
+ }
1091
+
1061
1092
  .btn-theme {
1093
+ min-height: 44px;
1094
+ padding: 10px 16px;
1095
+ width: 100%;
1096
+ justify-content: center;
1097
+ }
1098
+
1099
+ .header-info {
1100
+ flex-direction: column;
1101
+ align-items: flex-start;
1102
+ gap: 8px;
1103
+ }
1104
+
1105
+ .header-info .info-separator {
1062
1106
  display: none;
1063
1107
  }
1064
1108
 
1065
- .report-section {
1066
- break-inside: avoid;
1109
+ .info-item {
1110
+ font-size: 14px;
1111
+ line-height: 1.5;
1112
+ word-break: break-all;
1113
+ }
1114
+
1115
+ .section-header h2 {
1116
+ font-size: clamp(1rem, 4.5vw, 1.125rem);
1117
+ }
1118
+
1119
+ .marketing-text {
1120
+ font-size: 14px;
1121
+ padding: 12px;
1122
+ line-height: 1.65;
1123
+ }
1124
+
1125
+ .marketing-text strong {
1126
+ font-size: 17px;
1127
+ }
1128
+
1129
+ .health-overview {
1130
+ flex-direction: column;
1131
+ gap: 20px;
1132
+ }
1133
+
1134
+ .loading-speed-charts {
1135
+ flex-direction: column;
1136
+ align-items: center;
1137
+ gap: 16px;
1138
+ }
1139
+
1140
+ .longterm-cards,
1141
+ .module-items-grid,
1142
+ .priority-items,
1143
+ .priority-columns {
1144
+ grid-template-columns: 1fr !important;
1145
+ }
1146
+
1147
+ .priority-items {
1148
+ display: grid !important;
1149
+ gap: 12px;
1150
+ }
1151
+
1152
+ .data-table-wrapper,
1153
+ .risk-table-wrapper {
1154
+ margin-inline: -4px;
1155
+ overflow-x: auto;
1156
+ overscroll-behavior-x: contain;
1157
+ -webkit-overflow-scrolling: touch;
1158
+ }
1159
+
1160
+ .data-table,
1161
+ .risk-table {
1162
+ min-width: 480px;
1163
+ font-size: 13px;
1164
+ }
1165
+
1166
+ .score-ring-wrapper {
1167
+ transform: scale(0.92);
1168
+ transform-origin: center top;
1067
1169
  }
1068
1170
  }
1069
1171
  </style>
@@ -9,11 +9,11 @@ $ErrorActionPreference = 'Stop'
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  $PKG_NAME = 'siluzan-tso-cli'
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- $PKG_VERSION = '1.1.30'
12
+ $PKG_VERSION = '1.1.31-beta.2'
13
13
  $CLI_BIN = 'siluzan-tso'
14
14
  $SKILL_LABEL = 'Siluzan TSO'
15
- $INSTALL_CMD = 'npm install -g siluzan-tso-cli'
16
- $WEB_BASE = 'https://www.siluzan.com'
15
+ $INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
16
+ $WEB_BASE = 'https://www-ci.siluzan.com'
17
17
 
18
18
  # -- Constants ----------------------------------------------------------------
19
19
  $NODE_MAJOR_MIN = 18
@@ -9,11 +9,11 @@ set -euo pipefail
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  readonly PKG_NAME="siluzan-tso-cli"
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- readonly PKG_VERSION="1.1.30"
12
+ readonly PKG_VERSION="1.1.31-beta.2"
13
13
  readonly CLI_BIN="siluzan-tso"
14
14
  readonly SKILL_LABEL="Siluzan TSO"
15
- readonly INSTALL_CMD="npm install -g siluzan-tso-cli"
16
- readonly WEB_BASE="https://www.siluzan.com"
15
+ readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
16
+ readonly WEB_BASE="https://www-ci.siluzan.com"
17
17
 
18
18
  # -- Constants ----------------------------------------------------------------
19
19
  readonly NODE_MAJOR_MIN=18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-tso-cli",
3
- "version": "1.1.30",
3
+ "version": "1.1.31-beta.2",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "keywords": [
6
6
  "ad-account",
@@ -1,45 +0,0 @@
1
- # 报告模板纲要(report-templates)
2
-
3
- > **Agent Read 路径(推荐)**:`references/report-templates/<文件名>.md`
4
- > **同源副本**:`report-templates/<文件名>.md`(Skill 根目录,与 HTML 样式模板同目录)
5
- > **HTML 样式参考**(仅排版,不定义章节):`report-templates/report-template*.html`、`report-templates/*-report.html`
6
-
7
- 安装包构建时会将根目录 `report-templates/*.md` **同步到本目录**,避免 Agent 按 `references/` 前缀查找时 404。
8
-
9
- ---
10
-
11
- ## 周期 / 账户报告
12
-
13
- | 文件 | 工作流 | 说明 |
14
- | ---------------------------------- | --------- | ------------------------------------- |
15
- | `google-period-report.md` | **P4** | Google 账户周期报告(默认 HTML 纲要) |
16
- | `google-period-report-excel.md` | **P4** | 用户要 Excel 时全文必读 |
17
- | `meta-period-report.md` | **P4-FB** | Meta/Facebook 周期报告(默认 HTML) |
18
- | `meta-period-report-excel.md` | **P4-FB** | Meta Excel 五 Sheet |
19
- | `meta-account-diagnosis-report.md` | **P4-FB** | Meta 深度诊断 |
20
- | `tiktok-period-report.md` | **P4** | TikTok 周期报告 |
21
- | `bing-period-report.md` | **P4** | Bing 周期报告 |
22
-
23
- ## 诊断 / 专项
24
-
25
- | 文件 | 工作流 | 说明 |
26
- | ------------------------------------ | ------ | ------------------------------------------- |
27
- | `google-ads-diagnosis.md` | **P1** | Google 广告诊断完整纲要 |
28
- | `google-account-diagnosis-report.md` | **P1** | Google 账户深度诊断 |
29
- | `website-diagnosis-report.md` | **P8** | 网站诊断(配合 `website-diagnosis render`) |
30
- | `market-analysis-report.md` | **P9** | 战略市场分析交付检查清单 |
31
-
32
- ## 客户交付 / Excel
33
-
34
- | 文件 | 工作流 | 说明 |
35
- | ------------------------------ | ------ | --------------------------- |
36
- | `okki-weekly-google-client.md` | **P6** | OKKI 周报(全文必读) |
37
- | `google-inquiry-analysis.md` | **P7** | Google 询盘分析(全文必读) |
38
-
39
- ## 通用
40
-
41
- | 文件 | 说明 |
42
- | -------------------- | ---------------- |
43
- | `REPORT-WORKFLOW.md` | 六步报告流程总览 |
44
-
45
- 章节细则另见 `references/core/playbooks.md`(P1–P9)、`references/core/intent-routing.md`(模糊话术消歧)与 `references/analytics/account-analytics.md`。