@yaoxiu/marketing-dsl 2.4.0 → 2.5.0

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.
@@ -860,7 +860,12 @@ var sections4 = [
860
860
  {
861
861
  t: "note",
862
862
  tone: "info",
863
- text: "**\u76EE\u524D\u5DF2\u6CE8\u518C\u7684\u6570\u636E\u6E90**\uFF1A`shopAchievements`\uFF08\u5E97\u94FA\u6210\u679C\u7EDF\u8BA1\uFF0C\u8FD4\u56DE\u9879\u5B57\u6BB5 `v` \u52A8\u8BCD / `n` \u6570\u5B57 / `u` \u5355\u4F4D / `l` \u8BF4\u660E\uFF0C\u793A\u4F8B \u2462\u2463 \u7684\u6210\u679C\u683C\u5B50\u7528\u7684\u5C31\u662F\u5B83\uFF09\u3001`listRenewTiers`\uFF08\u7EED\u8D39\u4EF7\u683C\u6863\u4F4D\uFF0C\u5B57\u6BB5 `key` / `p` / `price` / `per` / `flag` / `hot` / `url`\uFF0C\u89C1\u793A\u4F8B \u2462\uFF09\u3002\u8981\u65B0\u7684\u627E\u524D\u7AEF\u767B\u8BB0\u3002"
863
+ text: "**\u76EE\u524D\u5DF2\u6CE8\u518C\u7684\u6570\u636E\u6E90**\uFF1A`userStatistics`\uFF08\u7528\u6237\u6570\u636E\u7EDF\u8BA1\uFF0C\u8FD4\u56DE\u4E00\u4E2A**\u6241\u5E73\u5BF9\u8C61**\u800C\u4E0D\u662F\u6570\u7EC4\uFF0C\u5B57\u6BB5\u540D\u5C31\u662F\u540E\u7AEF\u7684 snake_case\uFF0C\u5982 `move_success_count` \u7D2F\u8BA1\u642C\u5BB6\u6210\u529F\u6570 / `balance` \u642C\u5BB6\u6B21\u6570\u4F59\u989D / `ai_optimize_count` AI \u81EA\u52A8\u4F18\u5316\u6B21\u6570 / `white_image_fill_count` \u8865\u767D\u5E95\u56FE\u6B21\u6570\uFF0C\u793A\u4F8B \u2462\u2463 \u7684\u6210\u679C\u683C\u5B50\u7528\u7684\u5C31\u662F\u5B83\uFF09\u3001`listRenewTiers`\uFF08\u7EED\u8D39\u4EF7\u683C\u6863\u4F4D**\u6570\u7EC4**\uFF0C\u9879\u5B57\u6BB5 `key` / `p` / `price` / `per` / `flag` / `hot` / `url`\uFF0C\u89C1\u793A\u4F8B \u2462\uFF09\u3002\u8981\u65B0\u7684\u627E\u524D\u7AEF\u767B\u8BB0\u3002"
864
+ },
865
+ {
866
+ t: "note",
867
+ tone: "warn",
868
+ text: '**\u8FD4\u56DE\u6241\u5E73\u5BF9\u8C61\u7684\u6570\u636E\u6E90\uFF08\u5982 `userStatistics`\uFF09\u4E0D\u80FD\u7528 `repeat` \u7684 `bind` \u904D\u5386**\uFF0C\u683C\u5B50\u53EA\u80FD\u4E00\u4E2A\u4E2A\u5199\uFF0C\u6BCF\u683C\u76F4\u63A5\u63D2\u503C `{{ stat.move_success_count }}`\u3002\u4E5F\u4E0D\u8981\u8BD5\u56FE\u5728 `data` \u7684\u5199\u6B7B\u6570\u7EC4\u91CC\u585E `{{ }}` \u518D\u9760 `bind` \u5C55\u5F00 \u2014\u2014 `data` \u91CC\u7684\u9759\u6001\u503C\u539F\u6837\u5B58\uFF0C`{{ }}` \u53EA\u5728\u6E32\u67D3\u8282\u70B9\u65F6\u6C42\u503C\u4E00\u6B21\uFF0C`{{ item.n }}` \u6C42\u51FA\u6765\u662F\u5B57\u7B26\u4E32 `"{{ stat.xxx }}"`\uFF0C**\u4E0D\u4F1A\u4E8C\u6B21\u6C42\u503C**\uFF0C\u9875\u9762\u4E0A\u4F1A\u539F\u6837\u663E\u793A\u8FD9\u4E00\u4E32\u82B1\u62EC\u53F7\u3002'
864
869
  },
865
870
  {
866
871
  t: "p",
@@ -1944,7 +1949,7 @@ var meta_default = meta;
1944
1949
 
1945
1950
  // src/docs/examples/renew-expire.ts
1946
1951
  var ORANGE = "linear-gradient(90deg,#ff7a00,#faad14)";
1947
- var achieveCell = {
1952
+ var achieveCell = (verb, field, unit, label) => ({
1948
1953
  type: "flex",
1949
1954
  style: {
1950
1955
  direction: "column",
@@ -1966,7 +1971,7 @@ var achieveCell = {
1966
1971
  children: [
1967
1972
  {
1968
1973
  type: "text",
1969
- content: "{{ item.v }}",
1974
+ content: verb,
1970
1975
  style: {
1971
1976
  fontSize: 11.5,
1972
1977
  fontWeight: "600",
@@ -1976,23 +1981,23 @@ var achieveCell = {
1976
1981
  },
1977
1982
  {
1978
1983
  type: "text",
1979
- content: "{{ item.n }}",
1984
+ content: `{{ stat.${field} }}`,
1980
1985
  style: { fontSize: 20, fontWeight: "800", lineHeight: 1.1, color: "#ffffff" }
1981
1986
  },
1982
1987
  {
1983
1988
  type: "text",
1984
- content: "{{ item.u }}",
1989
+ content: ` ${unit}`,
1985
1990
  style: { fontSize: 12, lineHeight: 1.1, color: "rgba(255,255,255,0.92)" }
1986
1991
  }
1987
1992
  ]
1988
1993
  },
1989
1994
  {
1990
1995
  type: "text",
1991
- content: "{{ item.l }}",
1996
+ content: label,
1992
1997
  style: { fontSize: 11.5, lineHeight: 1.35, color: "rgba(255,255,255,0.72)" }
1993
1998
  }
1994
1999
  ]
1995
- };
2000
+ });
1996
2001
  var loseRow = {
1997
2002
  type: "flex",
1998
2003
  style: { align: "center", gap: 8, padding: "8px 0" },
@@ -2112,9 +2117,9 @@ var renewExpire = {
2112
2117
  style: { radius: 18 }
2113
2118
  },
2114
2119
  data: {
2115
- // 成果格子同样走数据源(字段 v / n / u / l 与 achieveCell 模板对应),
2116
- // 后端返回几格就渲染几格
2117
- achieve: { $source: "shopAchievements" },
2120
+ // 成果格子同样走数据源。userStatistics 返回扁平对象,字段名是后端的 snake_case,
2121
+ // 下面四格各自直接插值 {{ stat.xxx }}(扁平对象没法 bind 遍历,见文件头注释)
2122
+ stat: { $source: "userStatistics" },
2118
2123
  lose: [
2119
2124
  { b: "\u6279\u91CF\u642C\u5BB6\u4E0A\u8D27", t: "\u5230\u671F\u540E\u65E0\u6CD5\u7EE7\u7EED\u4E0A\u8D27" },
2120
2125
  { b: "6 \u9879\u81EA\u52A8\u7ECF\u8425\u4EFB\u52A1", t: "\u767D\u5E95\u56FE / \u77ED\u6807\u9898\u8865\u9F50\u3001\u4F4E\u6548\u54C1\u8BCA\u65AD\u4F18\u5316" },
@@ -2152,10 +2157,20 @@ var renewExpire = {
2152
2157
  }
2153
2158
  },
2154
2159
  {
2155
- type: "repeat",
2156
- bind: "achieve",
2160
+ // 四格并列写死(扁平对象没法 bind 遍历),flex + wrap 排成 2×2
2161
+ type: "flex",
2157
2162
  style: { gap: 9, wrap: true },
2158
- template: achieveCell
2163
+ children: [
2164
+ achieveCell("\u5DF2\u4E0A\u67B6", "move_success_count", "\u4E2A", "\u7D2F\u8BA1\u642C\u5BB6\u6210\u529F"),
2165
+ achieveCell("\u8FD0\u884C", "operate_task_count", "\u9879", "\u81EA\u52A8\u7ECF\u8425\u4EFB\u52A1"),
2166
+ achieveCell(
2167
+ "\u5DF2\u8865\u9F50",
2168
+ "white_image_fill_count",
2169
+ "\u5F20",
2170
+ "\u767D\u5E95\u56FE \xB7 \u5408\u89C4\u53EF\u62A5\u6D3B\u52A8"
2171
+ ),
2172
+ achieveCell("\u5B8C\u6210", "ai_optimize_count", "\u6B21", "AI \u81EA\u52A8\u4F18\u5316")
2173
+ ]
2159
2174
  }
2160
2175
  ]
2161
2176
  },
@@ -2292,7 +2307,7 @@ var cdSeparator = (content) => ({
2292
2307
  content,
2293
2308
  style: { fontSize: 13, fontWeight: "800", color: "rgba(255,255,255,0.7)" }
2294
2309
  });
2295
- var achieveCell2 = {
2310
+ var achieveCell2 = (verb, field, unit, label) => ({
2296
2311
  type: "flex",
2297
2312
  style: {
2298
2313
  direction: "column",
@@ -2312,7 +2327,7 @@ var achieveCell2 = {
2312
2327
  children: [
2313
2328
  {
2314
2329
  type: "text",
2315
- content: "{{ item.v }}",
2330
+ content: verb,
2316
2331
  style: {
2317
2332
  fontSize: 11.5,
2318
2333
  fontWeight: "600",
@@ -2322,23 +2337,23 @@ var achieveCell2 = {
2322
2337
  },
2323
2338
  {
2324
2339
  type: "text",
2325
- content: "{{ item.n }}",
2340
+ content: `{{ stat.${field} }}`,
2326
2341
  style: { fontSize: 20, fontWeight: "800", lineHeight: 1.1, color: "#ffffff" }
2327
2342
  },
2328
2343
  {
2329
2344
  type: "text",
2330
- content: "{{ item.u }}",
2345
+ content: ` ${unit}`,
2331
2346
  style: { fontSize: 12, lineHeight: 1.1, color: "rgba(255,255,255,0.92)" }
2332
2347
  }
2333
2348
  ]
2334
2349
  },
2335
2350
  {
2336
2351
  type: "text",
2337
- content: "{{ item.l }}",
2352
+ content: label,
2338
2353
  style: { fontSize: 11.5, lineHeight: 1.35, color: "rgba(255,255,255,0.72)" }
2339
2354
  }
2340
2355
  ]
2341
- };
2356
+ });
2342
2357
  var loseRow2 = {
2343
2358
  type: "flex",
2344
2359
  style: { align: "flex-start", gap: 10, padding: "7px 0" },
@@ -2477,9 +2492,10 @@ var lastDay = {
2477
2492
  },
2478
2493
  data: {
2479
2494
  // 成果格子的数字是**实时统计**,写死就会跟店铺实际情况对不上 —— 走后端数据源。
2480
- // $source 填的是宿主注册过的数据源名(不是接口地址),返回项的字段
2481
- // v / n / u / l 与下面 achieveCell 模板里的 {{ item.x }} 一一对应。
2482
- achieve: { $source: "shopAchievements" },
2495
+ // $source 填的是宿主注册过的数据源名(不是接口地址)。
2496
+ // userStatistics 返回一个扁平对象,字段名就是后端的 snake_case,
2497
+ // 下面四格各自直接插值 {{ stat.xxx }}(见文件头注释:扁平对象没法 bind 遍历)。
2498
+ stat: { $source: "userStatistics" },
2483
2499
  lose: [
2484
2500
  {
2485
2501
  b: "118 \u4E2A\u5546\u54C1\u7684\u5168\u90E8\u4F18\u5316\u8BB0\u5F55",
@@ -2570,10 +2586,25 @@ var lastDay = {
2570
2586
  }
2571
2587
  },
2572
2588
  {
2573
- type: "repeat",
2574
- bind: "achieve",
2589
+ // 四格并列写死(扁平对象没法 bind 遍历),flex + wrap 排成 2×2
2590
+ type: "flex",
2575
2591
  style: { gap: 9, wrap: true, marginTop: 14 },
2576
- template: achieveCell2
2592
+ children: [
2593
+ achieveCell2("\u5DF2\u4E0A\u67B6", "move_success_count", "\u4E2A", "\u7D2F\u8BA1\u642C\u5BB6\u6210\u529F"),
2594
+ achieveCell2(
2595
+ "\u8FD0\u884C",
2596
+ "operate_task_count",
2597
+ "\u9879",
2598
+ "\u7ECF\u8425\u4EFB\u52A1\uFF08\u5546\u54C1\u4F18\u5316/\u6D41\u91CF\u589E\u957F\uFF09"
2599
+ ),
2600
+ achieveCell2(
2601
+ "\u5DF2\u8865\u9F50",
2602
+ "white_image_fill_count",
2603
+ "\u5F20",
2604
+ "\u767D\u5E95\u56FE \xB7 \u5408\u89C4\u53EF\u62A5\u6D3B\u52A8"
2605
+ ),
2606
+ achieveCell2("\u5B8C\u6210", "ai_optimize_count", "\u6B21", "AI \u81EA\u52A8\u4F18\u5316")
2607
+ ]
2577
2608
  },
2578
2609
  // ===== 分格倒计时 + 厘秒逐帧动画 =====
2579
2610
  {
@@ -699,7 +699,12 @@ var sections4 = [
699
699
  {
700
700
  t: "note",
701
701
  tone: "info",
702
- text: "**\u76EE\u524D\u5DF2\u6CE8\u518C\u7684\u6570\u636E\u6E90**\uFF1A`shopAchievements`\uFF08\u5E97\u94FA\u6210\u679C\u7EDF\u8BA1\uFF0C\u8FD4\u56DE\u9879\u5B57\u6BB5 `v` \u52A8\u8BCD / `n` \u6570\u5B57 / `u` \u5355\u4F4D / `l` \u8BF4\u660E\uFF0C\u793A\u4F8B \u2462\u2463 \u7684\u6210\u679C\u683C\u5B50\u7528\u7684\u5C31\u662F\u5B83\uFF09\u3001`listRenewTiers`\uFF08\u7EED\u8D39\u4EF7\u683C\u6863\u4F4D\uFF0C\u5B57\u6BB5 `key` / `p` / `price` / `per` / `flag` / `hot` / `url`\uFF0C\u89C1\u793A\u4F8B \u2462\uFF09\u3002\u8981\u65B0\u7684\u627E\u524D\u7AEF\u767B\u8BB0\u3002"
702
+ text: "**\u76EE\u524D\u5DF2\u6CE8\u518C\u7684\u6570\u636E\u6E90**\uFF1A`userStatistics`\uFF08\u7528\u6237\u6570\u636E\u7EDF\u8BA1\uFF0C\u8FD4\u56DE\u4E00\u4E2A**\u6241\u5E73\u5BF9\u8C61**\u800C\u4E0D\u662F\u6570\u7EC4\uFF0C\u5B57\u6BB5\u540D\u5C31\u662F\u540E\u7AEF\u7684 snake_case\uFF0C\u5982 `move_success_count` \u7D2F\u8BA1\u642C\u5BB6\u6210\u529F\u6570 / `balance` \u642C\u5BB6\u6B21\u6570\u4F59\u989D / `ai_optimize_count` AI \u81EA\u52A8\u4F18\u5316\u6B21\u6570 / `white_image_fill_count` \u8865\u767D\u5E95\u56FE\u6B21\u6570\uFF0C\u793A\u4F8B \u2462\u2463 \u7684\u6210\u679C\u683C\u5B50\u7528\u7684\u5C31\u662F\u5B83\uFF09\u3001`listRenewTiers`\uFF08\u7EED\u8D39\u4EF7\u683C\u6863\u4F4D**\u6570\u7EC4**\uFF0C\u9879\u5B57\u6BB5 `key` / `p` / `price` / `per` / `flag` / `hot` / `url`\uFF0C\u89C1\u793A\u4F8B \u2462\uFF09\u3002\u8981\u65B0\u7684\u627E\u524D\u7AEF\u767B\u8BB0\u3002"
703
+ },
704
+ {
705
+ t: "note",
706
+ tone: "warn",
707
+ text: '**\u8FD4\u56DE\u6241\u5E73\u5BF9\u8C61\u7684\u6570\u636E\u6E90\uFF08\u5982 `userStatistics`\uFF09\u4E0D\u80FD\u7528 `repeat` \u7684 `bind` \u904D\u5386**\uFF0C\u683C\u5B50\u53EA\u80FD\u4E00\u4E2A\u4E2A\u5199\uFF0C\u6BCF\u683C\u76F4\u63A5\u63D2\u503C `{{ stat.move_success_count }}`\u3002\u4E5F\u4E0D\u8981\u8BD5\u56FE\u5728 `data` \u7684\u5199\u6B7B\u6570\u7EC4\u91CC\u585E `{{ }}` \u518D\u9760 `bind` \u5C55\u5F00 \u2014\u2014 `data` \u91CC\u7684\u9759\u6001\u503C\u539F\u6837\u5B58\uFF0C`{{ }}` \u53EA\u5728\u6E32\u67D3\u8282\u70B9\u65F6\u6C42\u503C\u4E00\u6B21\uFF0C`{{ item.n }}` \u6C42\u51FA\u6765\u662F\u5B57\u7B26\u4E32 `"{{ stat.xxx }}"`\uFF0C**\u4E0D\u4F1A\u4E8C\u6B21\u6C42\u503C**\uFF0C\u9875\u9762\u4E0A\u4F1A\u539F\u6837\u663E\u793A\u8FD9\u4E00\u4E32\u82B1\u62EC\u53F7\u3002'
703
708
  },
704
709
  {
705
710
  t: "p",
@@ -1783,7 +1788,7 @@ var meta_default = meta;
1783
1788
 
1784
1789
  // src/docs/examples/renew-expire.ts
1785
1790
  var ORANGE = "linear-gradient(90deg,#ff7a00,#faad14)";
1786
- var achieveCell = {
1791
+ var achieveCell = (verb, field, unit, label) => ({
1787
1792
  type: "flex",
1788
1793
  style: {
1789
1794
  direction: "column",
@@ -1805,7 +1810,7 @@ var achieveCell = {
1805
1810
  children: [
1806
1811
  {
1807
1812
  type: "text",
1808
- content: "{{ item.v }}",
1813
+ content: verb,
1809
1814
  style: {
1810
1815
  fontSize: 11.5,
1811
1816
  fontWeight: "600",
@@ -1815,23 +1820,23 @@ var achieveCell = {
1815
1820
  },
1816
1821
  {
1817
1822
  type: "text",
1818
- content: "{{ item.n }}",
1823
+ content: `{{ stat.${field} }}`,
1819
1824
  style: { fontSize: 20, fontWeight: "800", lineHeight: 1.1, color: "#ffffff" }
1820
1825
  },
1821
1826
  {
1822
1827
  type: "text",
1823
- content: "{{ item.u }}",
1828
+ content: ` ${unit}`,
1824
1829
  style: { fontSize: 12, lineHeight: 1.1, color: "rgba(255,255,255,0.92)" }
1825
1830
  }
1826
1831
  ]
1827
1832
  },
1828
1833
  {
1829
1834
  type: "text",
1830
- content: "{{ item.l }}",
1835
+ content: label,
1831
1836
  style: { fontSize: 11.5, lineHeight: 1.35, color: "rgba(255,255,255,0.72)" }
1832
1837
  }
1833
1838
  ]
1834
- };
1839
+ });
1835
1840
  var loseRow = {
1836
1841
  type: "flex",
1837
1842
  style: { align: "center", gap: 8, padding: "8px 0" },
@@ -1951,9 +1956,9 @@ var renewExpire = {
1951
1956
  style: { radius: 18 }
1952
1957
  },
1953
1958
  data: {
1954
- // 成果格子同样走数据源(字段 v / n / u / l 与 achieveCell 模板对应),
1955
- // 后端返回几格就渲染几格
1956
- achieve: { $source: "shopAchievements" },
1959
+ // 成果格子同样走数据源。userStatistics 返回扁平对象,字段名是后端的 snake_case,
1960
+ // 下面四格各自直接插值 {{ stat.xxx }}(扁平对象没法 bind 遍历,见文件头注释)
1961
+ stat: { $source: "userStatistics" },
1957
1962
  lose: [
1958
1963
  { b: "\u6279\u91CF\u642C\u5BB6\u4E0A\u8D27", t: "\u5230\u671F\u540E\u65E0\u6CD5\u7EE7\u7EED\u4E0A\u8D27" },
1959
1964
  { b: "6 \u9879\u81EA\u52A8\u7ECF\u8425\u4EFB\u52A1", t: "\u767D\u5E95\u56FE / \u77ED\u6807\u9898\u8865\u9F50\u3001\u4F4E\u6548\u54C1\u8BCA\u65AD\u4F18\u5316" },
@@ -1991,10 +1996,20 @@ var renewExpire = {
1991
1996
  }
1992
1997
  },
1993
1998
  {
1994
- type: "repeat",
1995
- bind: "achieve",
1999
+ // 四格并列写死(扁平对象没法 bind 遍历),flex + wrap 排成 2×2
2000
+ type: "flex",
1996
2001
  style: { gap: 9, wrap: true },
1997
- template: achieveCell
2002
+ children: [
2003
+ achieveCell("\u5DF2\u4E0A\u67B6", "move_success_count", "\u4E2A", "\u7D2F\u8BA1\u642C\u5BB6\u6210\u529F"),
2004
+ achieveCell("\u8FD0\u884C", "operate_task_count", "\u9879", "\u81EA\u52A8\u7ECF\u8425\u4EFB\u52A1"),
2005
+ achieveCell(
2006
+ "\u5DF2\u8865\u9F50",
2007
+ "white_image_fill_count",
2008
+ "\u5F20",
2009
+ "\u767D\u5E95\u56FE \xB7 \u5408\u89C4\u53EF\u62A5\u6D3B\u52A8"
2010
+ ),
2011
+ achieveCell("\u5B8C\u6210", "ai_optimize_count", "\u6B21", "AI \u81EA\u52A8\u4F18\u5316")
2012
+ ]
1998
2013
  }
1999
2014
  ]
2000
2015
  },
@@ -2131,7 +2146,7 @@ var cdSeparator = (content) => ({
2131
2146
  content,
2132
2147
  style: { fontSize: 13, fontWeight: "800", color: "rgba(255,255,255,0.7)" }
2133
2148
  });
2134
- var achieveCell2 = {
2149
+ var achieveCell2 = (verb, field, unit, label) => ({
2135
2150
  type: "flex",
2136
2151
  style: {
2137
2152
  direction: "column",
@@ -2151,7 +2166,7 @@ var achieveCell2 = {
2151
2166
  children: [
2152
2167
  {
2153
2168
  type: "text",
2154
- content: "{{ item.v }}",
2169
+ content: verb,
2155
2170
  style: {
2156
2171
  fontSize: 11.5,
2157
2172
  fontWeight: "600",
@@ -2161,23 +2176,23 @@ var achieveCell2 = {
2161
2176
  },
2162
2177
  {
2163
2178
  type: "text",
2164
- content: "{{ item.n }}",
2179
+ content: `{{ stat.${field} }}`,
2165
2180
  style: { fontSize: 20, fontWeight: "800", lineHeight: 1.1, color: "#ffffff" }
2166
2181
  },
2167
2182
  {
2168
2183
  type: "text",
2169
- content: "{{ item.u }}",
2184
+ content: ` ${unit}`,
2170
2185
  style: { fontSize: 12, lineHeight: 1.1, color: "rgba(255,255,255,0.92)" }
2171
2186
  }
2172
2187
  ]
2173
2188
  },
2174
2189
  {
2175
2190
  type: "text",
2176
- content: "{{ item.l }}",
2191
+ content: label,
2177
2192
  style: { fontSize: 11.5, lineHeight: 1.35, color: "rgba(255,255,255,0.72)" }
2178
2193
  }
2179
2194
  ]
2180
- };
2195
+ });
2181
2196
  var loseRow2 = {
2182
2197
  type: "flex",
2183
2198
  style: { align: "flex-start", gap: 10, padding: "7px 0" },
@@ -2316,9 +2331,10 @@ var lastDay = {
2316
2331
  },
2317
2332
  data: {
2318
2333
  // 成果格子的数字是**实时统计**,写死就会跟店铺实际情况对不上 —— 走后端数据源。
2319
- // $source 填的是宿主注册过的数据源名(不是接口地址),返回项的字段
2320
- // v / n / u / l 与下面 achieveCell 模板里的 {{ item.x }} 一一对应。
2321
- achieve: { $source: "shopAchievements" },
2334
+ // $source 填的是宿主注册过的数据源名(不是接口地址)。
2335
+ // userStatistics 返回一个扁平对象,字段名就是后端的 snake_case,
2336
+ // 下面四格各自直接插值 {{ stat.xxx }}(见文件头注释:扁平对象没法 bind 遍历)。
2337
+ stat: { $source: "userStatistics" },
2322
2338
  lose: [
2323
2339
  {
2324
2340
  b: "118 \u4E2A\u5546\u54C1\u7684\u5168\u90E8\u4F18\u5316\u8BB0\u5F55",
@@ -2409,10 +2425,25 @@ var lastDay = {
2409
2425
  }
2410
2426
  },
2411
2427
  {
2412
- type: "repeat",
2413
- bind: "achieve",
2428
+ // 四格并列写死(扁平对象没法 bind 遍历),flex + wrap 排成 2×2
2429
+ type: "flex",
2414
2430
  style: { gap: 9, wrap: true, marginTop: 14 },
2415
- template: achieveCell2
2431
+ children: [
2432
+ achieveCell2("\u5DF2\u4E0A\u67B6", "move_success_count", "\u4E2A", "\u7D2F\u8BA1\u642C\u5BB6\u6210\u529F"),
2433
+ achieveCell2(
2434
+ "\u8FD0\u884C",
2435
+ "operate_task_count",
2436
+ "\u9879",
2437
+ "\u7ECF\u8425\u4EFB\u52A1\uFF08\u5546\u54C1\u4F18\u5316/\u6D41\u91CF\u589E\u957F\uFF09"
2438
+ ),
2439
+ achieveCell2(
2440
+ "\u5DF2\u8865\u9F50",
2441
+ "white_image_fill_count",
2442
+ "\u5F20",
2443
+ "\u767D\u5E95\u56FE \xB7 \u5408\u89C4\u53EF\u62A5\u6D3B\u52A8"
2444
+ ),
2445
+ achieveCell2("\u5B8C\u6210", "ai_optimize_count", "\u6B21", "AI \u81EA\u52A8\u4F18\u5316")
2446
+ ]
2416
2447
  },
2417
2448
  // ===== 分格倒计时 + 厘秒逐帧动画 =====
2418
2449
  {
package/dist/index.cjs CHANGED
@@ -2314,10 +2314,10 @@ function formatIssues(issues) {
2314
2314
  }
2315
2315
 
2316
2316
  // src/host-capabilities.ts
2317
- var HOST_SOURCE_NAMES = ["shopAchievements", "listRenewTiers"];
2317
+ var HOST_SOURCE_NAMES = ["userStatistics", "listRenewTiers"];
2318
2318
  var HOST_HANDLER_NAMES = [];
2319
2319
  var HOST_SOURCE_LABELS = {
2320
- shopAchievements: "\u5E97\u94FA\u6210\u679C\u7EDF\u8BA1\uFF08\u5DF2\u4E0A\u67B6/\u8FD0\u884C\u4E2D/\u767D\u5E95\u56FE\u7B49\u683C\u5B50\u6570\u7EC4\uFF09",
2320
+ userStatistics: "\u7528\u6237\u6570\u636E\u7EDF\u8BA1\uFF08\u7D2F\u8BA1\u642C\u5BB6\u6570 / \u6B21\u6570\u4F59\u989D / AI \u4F18\u5316\u6B21\u6570\u7B49\uFF0C\u6241\u5E73\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u4E3A\u540E\u7AEF snake_case\uFF09",
2321
2321
  listRenewTiers: "\u7EED\u8D39\u4EF7\u683C\u6863\u4F4D\u5217\u8868\uFF08\u6708\u4ED8/\u5B63\u4ED8/\u534A\u5E74/\u5E74\u4ED8\uFF0C\u542B\u4E0B\u5355\u5730\u5740\uFF09"
2322
2322
  };
2323
2323
  var HOST_HANDLER_LABELS = {};
package/dist/index.d.cts CHANGED
@@ -166,7 +166,7 @@ declare function validateUserFields(dsl: unknown, allowed: string[]): FieldIssue
166
166
  *
167
167
  * 用 `as const` 是为了推导出 {@link HostSourceName} 联合类型,供前台约束注册表。
168
168
  */
169
- declare const HOST_SOURCE_NAMES: readonly ["shopAchievements", "listRenewTiers"];
169
+ declare const HOST_SOURCE_NAMES: readonly ["userStatistics", "listRenewTiers"];
170
170
  /** 数据源名的联合类型,前台注册表以它为键,漏注册一个就编译不过 */
171
171
  type HostSourceName = (typeof HOST_SOURCE_NAMES)[number];
172
172
  /**
package/dist/index.d.ts CHANGED
@@ -166,7 +166,7 @@ declare function validateUserFields(dsl: unknown, allowed: string[]): FieldIssue
166
166
  *
167
167
  * 用 `as const` 是为了推导出 {@link HostSourceName} 联合类型,供前台约束注册表。
168
168
  */
169
- declare const HOST_SOURCE_NAMES: readonly ["shopAchievements", "listRenewTiers"];
169
+ declare const HOST_SOURCE_NAMES: readonly ["userStatistics", "listRenewTiers"];
170
170
  /** 数据源名的联合类型,前台注册表以它为键,漏注册一个就编译不过 */
171
171
  type HostSourceName = (typeof HOST_SOURCE_NAMES)[number];
172
172
  /**
package/dist/index.js CHANGED
@@ -870,10 +870,10 @@ function createRuntime(dsl, options = {}) {
870
870
  }
871
871
 
872
872
  // src/host-capabilities.ts
873
- var HOST_SOURCE_NAMES = ["shopAchievements", "listRenewTiers"];
873
+ var HOST_SOURCE_NAMES = ["userStatistics", "listRenewTiers"];
874
874
  var HOST_HANDLER_NAMES = [];
875
875
  var HOST_SOURCE_LABELS = {
876
- shopAchievements: "\u5E97\u94FA\u6210\u679C\u7EDF\u8BA1\uFF08\u5DF2\u4E0A\u67B6/\u8FD0\u884C\u4E2D/\u767D\u5E95\u56FE\u7B49\u683C\u5B50\u6570\u7EC4\uFF09",
876
+ userStatistics: "\u7528\u6237\u6570\u636E\u7EDF\u8BA1\uFF08\u7D2F\u8BA1\u642C\u5BB6\u6570 / \u6B21\u6570\u4F59\u989D / AI \u4F18\u5316\u6B21\u6570\u7B49\uFF0C\u6241\u5E73\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u4E3A\u540E\u7AEF snake_case\uFF09",
877
877
  listRenewTiers: "\u7EED\u8D39\u4EF7\u683C\u6863\u4F4D\u5217\u8868\uFF08\u6708\u4ED8/\u5B63\u4ED8/\u534A\u5E74/\u5E74\u4ED8\uFF0C\u542B\u4E0B\u5355\u5730\u5740\uFF09"
878
878
  };
879
879
  var HOST_HANDLER_LABELS = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaoxiu/marketing-dsl",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "type": "module",
5
5
  "description": "营销弹窗 DSL 解释器核心,纯逻辑无框架依赖",
6
6
  "license": "MIT",