@yaoxiu/marketing-dsl 2.4.0 → 2.6.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",
@@ -1830,7 +1835,8 @@ var changelog = [
1830
1835
  "`zIndex` \u73B0\u5728\u4F1A\u81EA\u52A8\u5E26\u4E0A\u5B9A\u4F4D\u65B9\u5F0F\uFF1A`z-index` \u5BF9\u9759\u6001\u5143\u7D20\u662F\u6B7B\u58F0\u660E\uFF0C\u5199\u4E86\u4E0D\u751F\u6548\u3002\u6D41\u5F0F\u6392\u7248\u91CC\u9760\u8D1F `marginTop` \u5F80\u4E0A\u76D6\u7684\u5757\uFF08\u5982\u538B\u4F4F\u7EA2\u5934\u4E0B\u6CBF\u7684\u767D\u8272\u4E3B\u4F53\uFF09\u5FC5\u987B\u6709\u5C42\u7EA7\u624D\u76D6\u5F97\u4F4F\uFF0C\u914D\u4E86 `zIndex` \u5373\u53EF\uFF0C\u4E0D\u7528\uFF08\u4E5F\u6CA1\u6CD5\uFF09\u53E6\u914D `position`",
1831
1836
  "\u3010\u4FEE\u590D\u3011\u5F39\u51FA\u7B2C\u4E8C\u5C42\u5F39\u7A97\uFF08\u5982\u4E8C\u6B21\u633D\u7559\uFF09\u518D\u5173\u6389\u65F6\uFF0C\u4E0B\u5C42\u5F39\u7A97\u7684\u906E\u7F69\u5165\u573A\u52A8\u753B\u4F1A\u91CD\u64AD\u4E00\u904D\uFF0C\u80CC\u666F\u300C\u95EA\u300D\u4E00\u4E0B\u91CD\u65B0\u6DE1\u5165\u3002\u73B0\u5DF2\u4FEE\u6B63\uFF0C\u914D\u7F6E\u5199\u6CD5\u4E0D\u7528\u6539",
1832
1837
  "\u3010\u4FEE\u590D\u3011\u5207\u89C6\u56FE / \u5207 tab / `visibleWhen` \u7FFB\u8F6C\u65F6\uFF0C\u9875\u9762\u4E0A\u6B63\u5728\u8DD1\u7684\u5FAA\u73AF\u52A8\u753B\u4F1A\u5168\u90E8\u91CD\u5934\u64AD\u4E00\u904D\u3002\u73B0\u5DF2\u4FEE\u6B63",
1833
- "`hoverStyle` \u91CC\u7684 `{{ }}` \u53EA\u5728\u9996\u5C4F\u6C42\u503C\u4E00\u6B21\uFF0C\u4E4B\u540E\u4E0D\u968F state \u53D8\u5316\u2014\u2014\u8981\u8DDF\u7740\u72B6\u6001\u53D8\u7684\u6837\u5F0F\u5199\u5728 `style` \u91CC\uFF08\u90A3\u6761\u8DEF\u5F84\u6BCF\u5E27\u90FD\u4F1A\u91CD\u7B97\uFF09"
1838
+ "`hoverStyle` \u91CC\u7684 `{{ }}` \u53EA\u5728\u9996\u5C4F\u6C42\u503C\u4E00\u6B21\uFF0C\u4E4B\u540E\u4E0D\u968F state \u53D8\u5316\u2014\u2014\u8981\u8DDF\u7740\u72B6\u6001\u53D8\u7684\u6837\u5F0F\u5199\u5728 `style` \u91CC\uFF08\u90A3\u6761\u8DEF\u5F84\u6BCF\u5E27\u90FD\u4F1A\u91CD\u7B97\uFF09",
1839
+ "\u65B0\u589E\u793A\u4F8B \u246C \u642C\u5BB6\u6B21\u6570\u5C06\u5C3D\uFF1A\u989D\u5EA6\u8FDB\u5EA6\u6761\u7684\u6807\u51C6\u5199\u6CD5\uFF08\u5916\u5C42 flex \u5F53\u8F68\u9053 + \u5185\u5C42 box \u5F53\u586B\u5145\u6761 + `width` \u5199\u6210\u63D2\u503C\u8868\u8FBE\u5F0F\u73B0\u7B97\u767E\u5206\u6BD4\uFF09\uFF0C\u8981\u753B\u4EFB\u4F55\u6BD4\u4F8B\u6761\u90FD\u6284\u8FD9\u4EFD\u3002\u6CE8\u610F\u5B83\u7684\u603B\u989D\u5EA6\u662F\u8FD0\u8425\u624B\u586B\u7684\u2014\u2014\u7EDF\u8BA1\u63A5\u53E3\u76EE\u524D\u53EA\u6709\u4F59\u989D\u3001\u6CA1\u6709\u603B\u989D\u5EA6\uFF0C\u5957\u9910\u989D\u5EA6\u53D8\u4E86\u5FC5\u987B\u624B\u52A8\u6539\u7269\u6599"
1834
1840
  ]
1835
1841
  },
1836
1842
  {
@@ -1944,7 +1950,7 @@ var meta_default = meta;
1944
1950
 
1945
1951
  // src/docs/examples/renew-expire.ts
1946
1952
  var ORANGE = "linear-gradient(90deg,#ff7a00,#faad14)";
1947
- var achieveCell = {
1953
+ var achieveCell = (verb, field, unit, label) => ({
1948
1954
  type: "flex",
1949
1955
  style: {
1950
1956
  direction: "column",
@@ -1966,7 +1972,7 @@ var achieveCell = {
1966
1972
  children: [
1967
1973
  {
1968
1974
  type: "text",
1969
- content: "{{ item.v }}",
1975
+ content: verb,
1970
1976
  style: {
1971
1977
  fontSize: 11.5,
1972
1978
  fontWeight: "600",
@@ -1976,23 +1982,23 @@ var achieveCell = {
1976
1982
  },
1977
1983
  {
1978
1984
  type: "text",
1979
- content: "{{ item.n }}",
1985
+ content: `{{ stat.${field} }}`,
1980
1986
  style: { fontSize: 20, fontWeight: "800", lineHeight: 1.1, color: "#ffffff" }
1981
1987
  },
1982
1988
  {
1983
1989
  type: "text",
1984
- content: "{{ item.u }}",
1990
+ content: ` ${unit}`,
1985
1991
  style: { fontSize: 12, lineHeight: 1.1, color: "rgba(255,255,255,0.92)" }
1986
1992
  }
1987
1993
  ]
1988
1994
  },
1989
1995
  {
1990
1996
  type: "text",
1991
- content: "{{ item.l }}",
1997
+ content: label,
1992
1998
  style: { fontSize: 11.5, lineHeight: 1.35, color: "rgba(255,255,255,0.72)" }
1993
1999
  }
1994
2000
  ]
1995
- };
2001
+ });
1996
2002
  var loseRow = {
1997
2003
  type: "flex",
1998
2004
  style: { align: "center", gap: 8, padding: "8px 0" },
@@ -2112,9 +2118,9 @@ var renewExpire = {
2112
2118
  style: { radius: 18 }
2113
2119
  },
2114
2120
  data: {
2115
- // 成果格子同样走数据源(字段 v / n / u / l 与 achieveCell 模板对应),
2116
- // 后端返回几格就渲染几格
2117
- achieve: { $source: "shopAchievements" },
2121
+ // 成果格子同样走数据源。userStatistics 返回扁平对象,字段名是后端的 snake_case,
2122
+ // 下面四格各自直接插值 {{ stat.xxx }}(扁平对象没法 bind 遍历,见文件头注释)
2123
+ stat: { $source: "userStatistics" },
2118
2124
  lose: [
2119
2125
  { b: "\u6279\u91CF\u642C\u5BB6\u4E0A\u8D27", t: "\u5230\u671F\u540E\u65E0\u6CD5\u7EE7\u7EED\u4E0A\u8D27" },
2120
2126
  { 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 +2158,20 @@ var renewExpire = {
2152
2158
  }
2153
2159
  },
2154
2160
  {
2155
- type: "repeat",
2156
- bind: "achieve",
2161
+ // 四格并列写死(扁平对象没法 bind 遍历),flex + wrap 排成 2×2
2162
+ type: "flex",
2157
2163
  style: { gap: 9, wrap: true },
2158
- template: achieveCell
2164
+ children: [
2165
+ achieveCell("\u5DF2\u4E0A\u67B6", "move_success_count", "\u4E2A", "\u7D2F\u8BA1\u642C\u5BB6\u6210\u529F"),
2166
+ achieveCell("\u8FD0\u884C", "operate_task_count", "\u9879", "\u81EA\u52A8\u7ECF\u8425\u4EFB\u52A1"),
2167
+ achieveCell(
2168
+ "\u5DF2\u8865\u9F50",
2169
+ "white_image_fill_count",
2170
+ "\u5F20",
2171
+ "\u767D\u5E95\u56FE \xB7 \u5408\u89C4\u53EF\u62A5\u6D3B\u52A8"
2172
+ ),
2173
+ achieveCell("\u5B8C\u6210", "ai_optimize_count", "\u6B21", "AI \u81EA\u52A8\u4F18\u5316")
2174
+ ]
2159
2175
  }
2160
2176
  ]
2161
2177
  },
@@ -2292,7 +2308,7 @@ var cdSeparator = (content) => ({
2292
2308
  content,
2293
2309
  style: { fontSize: 13, fontWeight: "800", color: "rgba(255,255,255,0.7)" }
2294
2310
  });
2295
- var achieveCell2 = {
2311
+ var achieveCell2 = (verb, field, unit, label) => ({
2296
2312
  type: "flex",
2297
2313
  style: {
2298
2314
  direction: "column",
@@ -2312,7 +2328,7 @@ var achieveCell2 = {
2312
2328
  children: [
2313
2329
  {
2314
2330
  type: "text",
2315
- content: "{{ item.v }}",
2331
+ content: verb,
2316
2332
  style: {
2317
2333
  fontSize: 11.5,
2318
2334
  fontWeight: "600",
@@ -2322,23 +2338,23 @@ var achieveCell2 = {
2322
2338
  },
2323
2339
  {
2324
2340
  type: "text",
2325
- content: "{{ item.n }}",
2341
+ content: `{{ stat.${field} }}`,
2326
2342
  style: { fontSize: 20, fontWeight: "800", lineHeight: 1.1, color: "#ffffff" }
2327
2343
  },
2328
2344
  {
2329
2345
  type: "text",
2330
- content: "{{ item.u }}",
2346
+ content: ` ${unit}`,
2331
2347
  style: { fontSize: 12, lineHeight: 1.1, color: "rgba(255,255,255,0.92)" }
2332
2348
  }
2333
2349
  ]
2334
2350
  },
2335
2351
  {
2336
2352
  type: "text",
2337
- content: "{{ item.l }}",
2353
+ content: label,
2338
2354
  style: { fontSize: 11.5, lineHeight: 1.35, color: "rgba(255,255,255,0.72)" }
2339
2355
  }
2340
2356
  ]
2341
- };
2357
+ });
2342
2358
  var loseRow2 = {
2343
2359
  type: "flex",
2344
2360
  style: { align: "flex-start", gap: 10, padding: "7px 0" },
@@ -2477,9 +2493,10 @@ var lastDay = {
2477
2493
  },
2478
2494
  data: {
2479
2495
  // 成果格子的数字是**实时统计**,写死就会跟店铺实际情况对不上 —— 走后端数据源。
2480
- // $source 填的是宿主注册过的数据源名(不是接口地址),返回项的字段
2481
- // v / n / u / l 与下面 achieveCell 模板里的 {{ item.x }} 一一对应。
2482
- achieve: { $source: "shopAchievements" },
2496
+ // $source 填的是宿主注册过的数据源名(不是接口地址)。
2497
+ // userStatistics 返回一个扁平对象,字段名就是后端的 snake_case,
2498
+ // 下面四格各自直接插值 {{ stat.xxx }}(见文件头注释:扁平对象没法 bind 遍历)。
2499
+ stat: { $source: "userStatistics" },
2483
2500
  lose: [
2484
2501
  {
2485
2502
  b: "118 \u4E2A\u5546\u54C1\u7684\u5168\u90E8\u4F18\u5316\u8BB0\u5F55",
@@ -2570,10 +2587,25 @@ var lastDay = {
2570
2587
  }
2571
2588
  },
2572
2589
  {
2573
- type: "repeat",
2574
- bind: "achieve",
2590
+ // 四格并列写死(扁平对象没法 bind 遍历),flex + wrap 排成 2×2
2591
+ type: "flex",
2575
2592
  style: { gap: 9, wrap: true, marginTop: 14 },
2576
- template: achieveCell2
2593
+ children: [
2594
+ achieveCell2("\u5DF2\u4E0A\u67B6", "move_success_count", "\u4E2A", "\u7D2F\u8BA1\u642C\u5BB6\u6210\u529F"),
2595
+ achieveCell2(
2596
+ "\u8FD0\u884C",
2597
+ "operate_task_count",
2598
+ "\u9879",
2599
+ "\u7ECF\u8425\u4EFB\u52A1\uFF08\u5546\u54C1\u4F18\u5316/\u6D41\u91CF\u589E\u957F\uFF09"
2600
+ ),
2601
+ achieveCell2(
2602
+ "\u5DF2\u8865\u9F50",
2603
+ "white_image_fill_count",
2604
+ "\u5F20",
2605
+ "\u767D\u5E95\u56FE \xB7 \u5408\u89C4\u53EF\u62A5\u6D3B\u52A8"
2606
+ ),
2607
+ achieveCell2("\u5B8C\u6210", "ai_optimize_count", "\u6B21", "AI \u81EA\u52A8\u4F18\u5316")
2608
+ ]
2577
2609
  },
2578
2610
  // ===== 分格倒计时 + 厘秒逐帧动画 =====
2579
2611
  {
@@ -4723,6 +4755,437 @@ var giftRedPacket = {
4723
4755
  };
4724
4756
  var gift_red_packet_default = giftRedPacket;
4725
4757
 
4758
+ // src/docs/examples/quota-low.ts
4759
+ var ORANGE4 = "linear-gradient(90deg,#ff7a00,#faad14)";
4760
+ var USED = "{{ total - user.collectCount }}";
4761
+ var achieveCell3 = (verb, value, unit, label) => ({
4762
+ type: "flex",
4763
+ style: {
4764
+ direction: "column",
4765
+ width: "calc(50% - 5px)",
4766
+ background: "rgba(255,255,255,0.16)",
4767
+ borderWidth: 1,
4768
+ borderStyle: "solid",
4769
+ borderColor: "rgba(255,255,255,0.2)",
4770
+ radius: 10,
4771
+ padding: "10px 13px",
4772
+ gap: 3
4773
+ },
4774
+ children: [
4775
+ {
4776
+ // lineHeight 必须显式给,否则 20px 数字的默认行高会把格子撑高
4777
+ type: "flex",
4778
+ style: { align: "baseline", gap: 3, height: 22 },
4779
+ children: [
4780
+ {
4781
+ type: "text",
4782
+ content: verb,
4783
+ style: {
4784
+ fontSize: 11.5,
4785
+ fontWeight: "600",
4786
+ lineHeight: 1.1,
4787
+ color: "rgba(255,255,255,0.92)"
4788
+ }
4789
+ },
4790
+ {
4791
+ type: "text",
4792
+ content: value,
4793
+ style: { fontSize: 20, fontWeight: "800", lineHeight: 1.1, color: "#ffffff" }
4794
+ },
4795
+ {
4796
+ type: "text",
4797
+ content: ` ${unit}`,
4798
+ style: { fontSize: 12, lineHeight: 1.1, color: "rgba(255,255,255,0.92)" }
4799
+ }
4800
+ ]
4801
+ },
4802
+ {
4803
+ type: "text",
4804
+ content: label,
4805
+ style: { fontSize: 11.5, lineHeight: 1.35, color: "rgba(255,255,255,0.72)" }
4806
+ }
4807
+ ]
4808
+ });
4809
+ var loseRow3 = {
4810
+ type: "flex",
4811
+ style: { align: "flex-start", gap: 10, padding: "7px 0" },
4812
+ children: [
4813
+ {
4814
+ type: "text",
4815
+ content: "",
4816
+ style: { width: 6, height: 6, radius: "50%", background: "#f53f3f", marginTop: 7 }
4817
+ },
4818
+ {
4819
+ type: "flex",
4820
+ style: { align: "baseline", gap: 4, wrap: true, flex: "1" },
4821
+ children: [
4822
+ {
4823
+ type: "text",
4824
+ content: "{{ item.b }}",
4825
+ style: {
4826
+ fontSize: 12.5,
4827
+ fontWeight: "700",
4828
+ lineHeight: 1.55,
4829
+ color: "#1f2533"
4830
+ }
4831
+ },
4832
+ {
4833
+ type: "text",
4834
+ content: "{{ item.tag }}",
4835
+ visibleWhen: "item.tag != ''",
4836
+ style: {
4837
+ background: "{{ item.sev == 'lose' ? '#ffd5cf' : 'rgba(255,255,255,0.78)' }}",
4838
+ color: "{{ item.sev == 'lose' ? '#cf1322' : '#8a7f78' }}",
4839
+ fontSize: 10,
4840
+ fontWeight: "800",
4841
+ radius: 4,
4842
+ padding: "1px 6px",
4843
+ whiteSpace: "nowrap"
4844
+ }
4845
+ },
4846
+ {
4847
+ type: "text",
4848
+ content: "\u2014 {{ item.t }}",
4849
+ style: { fontSize: 12.5, lineHeight: 1.55, color: "#4a4038" }
4850
+ }
4851
+ ]
4852
+ }
4853
+ ]
4854
+ };
4855
+ var tierCard3 = {
4856
+ type: "box",
4857
+ style: {
4858
+ flex: "1",
4859
+ height: 121,
4860
+ radius: 12,
4861
+ background: "{{ item.key == current.key ? '#fffaf0' : '#ffffff' }}",
4862
+ borderStyle: "solid",
4863
+ borderWidth: "{{ item.key == current.key ? '2px' : '1px' }}",
4864
+ borderColor: "{{ item.key == current.key ? '#f0a000' : '#e5e8ed' }}",
4865
+ cursor: "pointer"
4866
+ },
4867
+ action: {
4868
+ type: "sequence",
4869
+ actions: [
4870
+ { type: "setState", key: "period", value: "{{ index }}" },
4871
+ {
4872
+ type: "track",
4873
+ event: "popup_period_select",
4874
+ params: { period: "{{ item.key }}" }
4875
+ }
4876
+ ]
4877
+ },
4878
+ children: [
4879
+ {
4880
+ type: "text",
4881
+ rect: ["calc(50% - 19px)", -9, 38, 22],
4882
+ content: "\u63A8\u8350",
4883
+ visibleWhen: "item.hot",
4884
+ style: {
4885
+ background: ORANGE4,
4886
+ color: "#ffffff",
4887
+ fontSize: 11,
4888
+ fontWeight: "800",
4889
+ radius: 6,
4890
+ textAlign: "center",
4891
+ lineHeight: 22
4892
+ }
4893
+ },
4894
+ {
4895
+ type: "text",
4896
+ rect: [0, 12, "100%", 19],
4897
+ content: "{{ item.p }}",
4898
+ style: { fontSize: 13, color: "#8a909c", textAlign: "center" }
4899
+ },
4900
+ {
4901
+ type: "flex",
4902
+ rect: [0, 34, "100%", 26],
4903
+ style: { justify: "center", align: "baseline" },
4904
+ children: [
4905
+ {
4906
+ type: "text",
4907
+ content: "\xA5",
4908
+ style: { fontSize: 13, fontWeight: "800", color: "#1f2533" }
4909
+ },
4910
+ {
4911
+ type: "text",
4912
+ content: "{{ item.price }}",
4913
+ style: { fontSize: 21, fontWeight: "800", color: "#1f2533" }
4914
+ }
4915
+ ]
4916
+ },
4917
+ {
4918
+ type: "text",
4919
+ rect: [4, 63, "calc(100% - 8px)", 32],
4920
+ content: "{{ item.per }}",
4921
+ style: { fontSize: 11, color: "#8a909c", textAlign: "center", lineHeight: 1.35 }
4922
+ },
4923
+ {
4924
+ type: "text",
4925
+ rect: [0, 98, "100%", 15],
4926
+ content: "{{ item.flag }}",
4927
+ visibleWhen: "item.flag != ''",
4928
+ style: { fontSize: 11, color: "#8a909c", textAlign: "center" }
4929
+ }
4930
+ ]
4931
+ };
4932
+ var quotaLow = {
4933
+ version: 1,
4934
+ type: "popup",
4935
+ meta: { name: "\u642C\u5BB6\u6B21\u6570\u5C06\u5C3D \xB7 \u989D\u5EA6\u8FDB\u5EA6\u6761\uFF08\u590D\u523B\u8FD0\u8425 demo\uFF09" },
4936
+ stage: {
4937
+ width: 520,
4938
+ height: "auto",
4939
+ layout: "flow",
4940
+ mask: true,
4941
+ maskClosable: false,
4942
+ closeButton: { show: true, position: "top-right", offset: [14, 14] },
4943
+ style: { radius: 18 }
4944
+ },
4945
+ data: {
4946
+ // 实时统计走后端数据源。$source 填的是宿主注册过的数据源名(不是接口地址),
4947
+ // userStatistics 返回扁平对象,字段名就是后端的 snake_case
4948
+ stat: { $source: "userStatistics" },
4949
+ // 总额度:运营按当前套餐手填。为什么不走接口、以后怎么换,见文件头注释
4950
+ total: 30,
4951
+ lose: [
4952
+ { b: "\u6279\u91CF\u642C\u5BB6", tag: "\u5C06\u505C\u7528", sev: "lose", t: "\u989D\u5EA6\u5F52\u96F6\u540E\u65E0\u6CD5\u7EE7\u7EED\u4E0A\u8D27" },
4953
+ {
4954
+ b: "1688 \u4E00\u4EF6\u4EE3\u53D1",
4955
+ tag: "\u5C06\u505C\u7528",
4956
+ sev: "lose",
4957
+ t: "\u6E90\u5934\u8D27\u6E90\u65AD\u4F9B\uFF0C\u9009\u54C1\u3001\u94FA\u8D27\u3001\u4EE3\u53D1\u90FD\u8981\u624B\u52A8\u505A"
4958
+ },
4959
+ {
4960
+ b: "AI \u81EA\u52A8\u4F18\u5316",
4961
+ tag: "\u5C06\u6682\u505C",
4962
+ sev: "pause",
4963
+ t: "\u65B0\u5546\u54C1\u4E0D\u518D\u8865\u4E3B\u6807\u9898 / \u77ED\u6807\u9898 / \u767D\u5E95\u56FE"
4964
+ }
4965
+ ],
4966
+ // 价格档位从后端数据源取,后端返回几档就渲染几档,配置时不用知道数量
4967
+ tiers: { $source: "listRenewTiers", params: { scene: "quota_low" } }
4968
+ },
4969
+ state: { period: 1 },
4970
+ derived: { current: { list: "tiers", indexBy: "period" } },
4971
+ nodes: [
4972
+ // ===== 深色渐变头部:标签 + 2×2 成果格 =====
4973
+ {
4974
+ type: "flex",
4975
+ style: {
4976
+ direction: "column",
4977
+ background: "linear-gradient(135deg,#2b0f0f,#3a1414)",
4978
+ padding: "20px 22px 16px",
4979
+ gap: 13
4980
+ },
4981
+ children: [
4982
+ {
4983
+ type: "text",
4984
+ content: "\u26A1 \u642C\u5BB6\u6B21\u6570\u5373\u5C06\u7528\u5B8C",
4985
+ style: {
4986
+ // 不写 alignSelf 会被 flex 列拉满整行,标签必须按内容宽度
4987
+ alignSelf: "flex-start",
4988
+ background: "rgba(255,255,255,0.18)",
4989
+ color: "#ffffff",
4990
+ fontSize: 12,
4991
+ fontWeight: "700",
4992
+ radius: 6,
4993
+ padding: "5px 10px"
4994
+ }
4995
+ },
4996
+ {
4997
+ // 四格并列写死(扁平对象没法 bind 遍历),flex + wrap 排成 2×2。
4998
+ // 第一格的数字不是统计字段,而是「总额度 − 剩余次数」现算出来的
4999
+ type: "flex",
5000
+ style: { gap: 9, wrap: true },
5001
+ children: [
5002
+ achieveCell3("\u5DF2\u7528", USED, "\u6B21", "\u642C\u5BB6\u6B21\u6570"),
5003
+ achieveCell3("\u5DF2\u4E0A\u67B6", "{{ stat.move_success_count }}", "\u4E2A", "\u7D2F\u8BA1\u4E0A\u67B6\u5546\u54C1"),
5004
+ achieveCell3("\u65E5\u5747", "{{ stat.avg_daily_move_count }}", "\u4E2A", "\u5E73\u5747\u6BCF\u5929\u4E0A\u67B6"),
5005
+ achieveCell3(
5006
+ "\u5DF2\u8865\u9F50",
5007
+ "{{ stat.white_image_fill_count }}",
5008
+ "\u5F20",
5009
+ "\u767D\u5E95\u56FE \xB7 \u5408\u89C4\u53EF\u62A5\u6D3B\u52A8"
5010
+ )
5011
+ ]
5012
+ }
5013
+ ]
5014
+ },
5015
+ // ===== 白色 body =====
5016
+ {
5017
+ type: "flex",
5018
+ style: { direction: "column", background: "#ffffff", padding: "22px 26px 24px" },
5019
+ children: [
5020
+ // ===== 额度进度条:轨道 + 填充条 + 百分比表达式(本示例的重点)=====
5021
+ {
5022
+ type: "flex",
5023
+ style: {
5024
+ direction: "column",
5025
+ background: "#fff8f3",
5026
+ radius: 10,
5027
+ padding: "8px 13px 9px",
5028
+ gap: 4
5029
+ },
5030
+ children: [
5031
+ {
5032
+ // 标题行:左边「剩余 N 次」,右边「已用 X / 总额度 次」
5033
+ type: "flex",
5034
+ style: { align: "baseline", justify: "space-between" },
5035
+ children: [
5036
+ {
5037
+ type: "flex",
5038
+ style: { align: "baseline", gap: 3 },
5039
+ children: [
5040
+ {
5041
+ type: "text",
5042
+ content: "\u642C\u5BB6\u6B21\u6570\u5269\u4F59",
5043
+ style: { fontSize: 12, lineHeight: 1.35, color: "#3f4656" }
5044
+ },
5045
+ {
5046
+ type: "text",
5047
+ content: "{{ user.collectCount }} \u6B21",
5048
+ style: {
5049
+ fontSize: 15,
5050
+ fontWeight: "800",
5051
+ lineHeight: 1.25,
5052
+ color: "#cf1322"
5053
+ }
5054
+ }
5055
+ ]
5056
+ },
5057
+ {
5058
+ type: "text",
5059
+ content: `\u5DF2\u7528 ${USED} / {{ total }} \u6B21`,
5060
+ style: { fontSize: 10.5, lineHeight: 1.35, color: "#8a909c" }
5061
+ }
5062
+ ]
5063
+ },
5064
+ {
5065
+ // 轨道。用 flex 而不是 box —— box 的子节点走绝对定位、必须给 rect,
5066
+ // 填充条要的是「跟着父级流」;overflow: hidden 必须写,否则填充条的
5067
+ // 直角会戳出轨道的圆角外面
5068
+ type: "flex",
5069
+ style: {
5070
+ height: 5,
5071
+ radius: 4,
5072
+ background: "#ffe0cc",
5073
+ overflow: "hidden"
5074
+ },
5075
+ children: [
5076
+ {
5077
+ // 填充条。宽度是算出来的:已用 ÷ 总额度 × 100,节点 style 里的
5078
+ // 字符串同样走插值,所以百分比不需要后端多下发一个字段
5079
+ type: "box",
5080
+ style: {
5081
+ width: "{{ (total - user.collectCount) / total * 100 }}%",
5082
+ height: "100%",
5083
+ background: "linear-gradient(90deg,#f53f3f,#ff7a45)"
5084
+ }
5085
+ }
5086
+ ]
5087
+ }
5088
+ ]
5089
+ },
5090
+ {
5091
+ type: "text",
5092
+ content: "\u642C\u5BB6\u6B21\u6570\u7528\u5B8C\uFF0C\u4EA7\u54C1\u80FD\u529B\u5C06\u53D7\u9650\uFF1A",
5093
+ style: { fontSize: 15, fontWeight: "800", color: "#1f2533", marginTop: 17 }
5094
+ },
5095
+ {
5096
+ type: "repeat",
5097
+ bind: "lose",
5098
+ template: loseRow3,
5099
+ style: {
5100
+ direction: "column",
5101
+ marginTop: 12,
5102
+ background: "#ffe9e6",
5103
+ borderWidth: 1,
5104
+ borderStyle: "solid",
5105
+ borderColor: "#ffd0ca",
5106
+ radius: 12,
5107
+ padding: "7px 13px"
5108
+ }
5109
+ },
5110
+ {
5111
+ type: "flex",
5112
+ style: { align: "center", gap: 8, marginTop: 17, marginBottom: 9 },
5113
+ children: [
5114
+ {
5115
+ type: "text",
5116
+ content: "\u7EED\u6EE1\u989D\u5EA6 \xB7 \u9009\u62E9\u5468\u671F",
5117
+ style: { fontSize: 13.5, fontWeight: "700", color: "#747b89" }
5118
+ },
5119
+ {
5120
+ type: "text",
5121
+ content: "\u65B0\u4EBA\u9996\u8D2D\u4EF7",
5122
+ style: {
5123
+ alignSelf: "center",
5124
+ background: ORANGE4,
5125
+ color: "#ffffff",
5126
+ fontSize: 11,
5127
+ fontWeight: "800",
5128
+ radius: 5,
5129
+ padding: "2px 8px"
5130
+ }
5131
+ }
5132
+ ]
5133
+ },
5134
+ { type: "repeat", bind: "tiers", style: { gap: 8 }, template: tierCard3 },
5135
+ {
5136
+ type: "flex",
5137
+ style: {
5138
+ justify: "center",
5139
+ align: "center",
5140
+ gap: 5,
5141
+ height: 52,
5142
+ radius: 11,
5143
+ background: "linear-gradient(90deg,#f53f3f,#ff7a45)",
5144
+ marginTop: 15,
5145
+ cursor: "pointer"
5146
+ },
5147
+ action: {
5148
+ type: "sequence",
5149
+ actions: [
5150
+ {
5151
+ type: "track",
5152
+ event: "popup_renew_click",
5153
+ params: { period: "{{ current.key }}", stage: "quota_low" }
5154
+ },
5155
+ { type: "navigate", url: "{{ current.url }}" }
5156
+ ]
5157
+ },
5158
+ children: [
5159
+ {
5160
+ type: "text",
5161
+ content: "\u7EED\u6EE1\u989D\u5EA6 \xB7",
5162
+ style: { fontSize: 14, fontWeight: "800", color: "#ffffff" }
5163
+ },
5164
+ {
5165
+ type: "text",
5166
+ content: "{{ current.p }} \xA5{{ current.price }}",
5167
+ style: { fontSize: 16.5, fontWeight: "800", color: "#ffffff" }
5168
+ }
5169
+ ]
5170
+ },
5171
+ {
5172
+ type: "text",
5173
+ content: "\u5347\u7EA7\u6216\u67E5\u770B\u66F4\u591A\u4EA7\u54C1\u5957\u9910",
5174
+ style: {
5175
+ fontSize: 12.5,
5176
+ color: "#8a909c",
5177
+ textAlign: "center",
5178
+ marginTop: 11,
5179
+ cursor: "pointer"
5180
+ },
5181
+ action: { type: "track", event: "popup_more_plans" }
5182
+ }
5183
+ ]
5184
+ }
5185
+ ]
5186
+ };
5187
+ var quota_low_default = quotaLow;
5188
+
4726
5189
  // src/docs/examples/index.ts
4727
5190
  var HOTSPOT_BG = "rgba(255,68,51,0.16)";
4728
5191
  var imageHotspot = {
@@ -4974,6 +5437,11 @@ var examples = [
4974
5437
  label: "\u246B \u590D\u523B\u7EBF\u4E0A\u5F39\u7A97 \xB7 1 \u5206\u94B1\u534A\u5E74\u5361\uFF08\u52A8\u753B\u6700\u5BC6\u7684\u4E00\u4EFD\uFF09",
4975
5438
  value: "giftRedPacket",
4976
5439
  dsl: gift_red_packet_default
5440
+ },
5441
+ {
5442
+ label: "\u246C \u590D\u523B\u8FD0\u8425 demo \xB7 \u642C\u5BB6\u6B21\u6570\u5C06\u5C3D\uFF08\u989D\u5EA6\u8FDB\u5EA6\u6761\uFF09",
5443
+ value: "quotaLow",
5444
+ dsl: quota_low_default
4977
5445
  }
4978
5446
  ];
4979
5447
  var examples_default = examples;
@@ -96,7 +96,8 @@ declare const meta: DocMeta;
96
96
  *
97
97
  * ①② 是最小骨架,③④ 是运营 demo 真实弹窗的完整复刻,⑤⑥ 是多视图,⑦ 是换肤换布局,
98
98
  * ⑧ 是通栏 banner(宽度由页面决定、只能声明比例),⑨⑩ 是商品编辑抽屉里两个**固定尺寸**坑位,
99
- * ⑪⑫ 是搬家成功页两个线上弹窗的一比一复刻(动画、hover、相对时长倒计时的完整用法)。
99
+ * ⑪⑫ 是搬家成功页两个线上弹窗的一比一复刻(动画、hover、相对时长倒计时的完整用法),
100
+ * ⑬ 是额度进度条(用表达式算填充宽度,要画任何比例条都抄这份)。
100
101
  * 后端数据源($source)用法见 ③。
101
102
  */
102
103
 
@@ -96,7 +96,8 @@ declare const meta: DocMeta;
96
96
  *
97
97
  * ①② 是最小骨架,③④ 是运营 demo 真实弹窗的完整复刻,⑤⑥ 是多视图,⑦ 是换肤换布局,
98
98
  * ⑧ 是通栏 banner(宽度由页面决定、只能声明比例),⑨⑩ 是商品编辑抽屉里两个**固定尺寸**坑位,
99
- * ⑪⑫ 是搬家成功页两个线上弹窗的一比一复刻(动画、hover、相对时长倒计时的完整用法)。
99
+ * ⑪⑫ 是搬家成功页两个线上弹窗的一比一复刻(动画、hover、相对时长倒计时的完整用法),
100
+ * ⑬ 是额度进度条(用表达式算填充宽度,要画任何比例条都抄这份)。
100
101
  * 后端数据源($source)用法见 ③。
101
102
  */
102
103