@tfdesign/b-end 1.0.4

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.
Files changed (176) hide show
  1. package/AI_READ_FIRST.md +131 -0
  2. package/LICENSE +21 -0
  3. package/README.md +353 -0
  4. package/package.json +67 -0
  5. package/scripts/check-tfds-contract.mjs +334 -0
  6. package/scripts/check-tfds-integration.mjs +263 -0
  7. package/scripts/postinstall-cursor-skill.mjs +382 -0
  8. package/scripts/setup.mjs +520 -0
  9. package/skills/tfds/CHECKLIST.md +205 -0
  10. package/skills/tfds/COMMON_FAILURES.md +238 -0
  11. package/skills/tfds/DESIGN_PRINCIPLES.md +477 -0
  12. package/skills/tfds/GLOBAL_DESIGN_RULES.md +636 -0
  13. package/skills/tfds/LAYOUT_RECIPES.md +140 -0
  14. package/skills/tfds/LAYOUT_RULES.md +1355 -0
  15. package/skills/tfds/PAGE_ARCHETYPES.md +201 -0
  16. package/skills/tfds/SKILL.md +188 -0
  17. package/skills/tfds/components.index.json +7305 -0
  18. package/skills/tfds/components.summary.json +1809 -0
  19. package/src/_b_end_runtime/components/AiSuggestionShared.jsx +166 -0
  20. package/src/_b_end_runtime/components/Avatar.jsx +325 -0
  21. package/src/_b_end_runtime/components/Avatar.tokens.js +76 -0
  22. package/src/_b_end_runtime/components/AvatarGridPreview.jsx +56 -0
  23. package/src/_b_end_runtime/components/AvatarGroup.jsx +80 -0
  24. package/src/_b_end_runtime/components/AvatarGroup.tokens.js +28 -0
  25. package/src/_b_end_runtime/components/Button.jsx +144 -0
  26. package/src/_b_end_runtime/components/Button.tokens.js +90 -0
  27. package/src/_b_end_runtime/components/Card.jsx +460 -0
  28. package/src/_b_end_runtime/components/Card.tokens.js +124 -0
  29. package/src/_b_end_runtime/components/CardPreview.jsx +51 -0
  30. package/src/_b_end_runtime/components/ChatBubble.jsx +384 -0
  31. package/src/_b_end_runtime/components/ChatBubble.tokens.js +60 -0
  32. package/src/_b_end_runtime/components/ChatBubblePreview.jsx +129 -0
  33. package/src/_b_end_runtime/components/ChatInput.jsx +1399 -0
  34. package/src/_b_end_runtime/components/ChatInput.tokens.js +75 -0
  35. package/src/_b_end_runtime/components/ChatMessage.jsx +2215 -0
  36. package/src/_b_end_runtime/components/ChatMessage.tokens.js +257 -0
  37. package/src/_b_end_runtime/components/ChatMessagePreview.jsx +388 -0
  38. package/src/_b_end_runtime/components/Checkbox.jsx +317 -0
  39. package/src/_b_end_runtime/components/Checkbox.tokens.js +59 -0
  40. package/src/_b_end_runtime/components/ConversationList.jsx +1264 -0
  41. package/src/_b_end_runtime/components/ConversationList.tokens.js +135 -0
  42. package/src/_b_end_runtime/components/ConversationListPreview.jsx +108 -0
  43. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.jsx +324 -0
  44. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.tokens.js +69 -0
  45. package/src/_b_end_runtime/components/DatePicker.jsx +739 -0
  46. package/src/_b_end_runtime/components/DatePicker.tokens.js +99 -0
  47. package/src/_b_end_runtime/components/Empty.jsx +141 -0
  48. package/src/_b_end_runtime/components/Empty.tokens.js +40 -0
  49. package/src/_b_end_runtime/components/Form.jsx +609 -0
  50. package/src/_b_end_runtime/components/Form.tokens.js +77 -0
  51. package/src/_b_end_runtime/components/FormFieldStack.jsx +123 -0
  52. package/src/_b_end_runtime/components/FormFieldStack.tokens.js +12 -0
  53. package/src/_b_end_runtime/components/FormTitle.jsx +119 -0
  54. package/src/_b_end_runtime/components/FormTitle.tokens.js +87 -0
  55. package/src/_b_end_runtime/components/FullScreenPage.jsx +97 -0
  56. package/src/_b_end_runtime/components/FullScreenPage.tokens.js +19 -0
  57. package/src/_b_end_runtime/components/Icon.jsx +172 -0
  58. package/src/_b_end_runtime/components/Icon.tokens.js +26 -0
  59. package/src/_b_end_runtime/components/IconGridPreview.jsx +277 -0
  60. package/src/_b_end_runtime/components/InfoDisplayPanel.jsx +620 -0
  61. package/src/_b_end_runtime/components/InfoDisplayPanel.tokens.js +71 -0
  62. package/src/_b_end_runtime/components/InfoDisplayPanelPreview.jsx +133 -0
  63. package/src/_b_end_runtime/components/Input.jsx +258 -0
  64. package/src/_b_end_runtime/components/Input.tokens.js +68 -0
  65. package/src/_b_end_runtime/components/InputNumber.jsx +242 -0
  66. package/src/_b_end_runtime/components/InputNumber.tokens.js +55 -0
  67. package/src/_b_end_runtime/components/Modal.jsx +155 -0
  68. package/src/_b_end_runtime/components/Modal.tokens.js +73 -0
  69. package/src/_b_end_runtime/components/NavBar.jsx +842 -0
  70. package/src/_b_end_runtime/components/NavBar.tokens.js +97 -0
  71. package/src/_b_end_runtime/components/NavBarPreview.jsx +11 -0
  72. package/src/_b_end_runtime/components/Radio.jsx +227 -0
  73. package/src/_b_end_runtime/components/Radio.tokens.js +59 -0
  74. package/src/_b_end_runtime/components/Select.jsx +766 -0
  75. package/src/_b_end_runtime/components/Select.tokens.js +99 -0
  76. package/src/_b_end_runtime/components/Sheet.jsx +132 -0
  77. package/src/_b_end_runtime/components/Sheet.tokens.js +61 -0
  78. package/src/_b_end_runtime/components/Slider.jsx +346 -0
  79. package/src/_b_end_runtime/components/Slider.tokens.js +47 -0
  80. package/src/_b_end_runtime/components/Switch.jsx +124 -0
  81. package/src/_b_end_runtime/components/Switch.tokens.js +38 -0
  82. package/src/_b_end_runtime/components/Table.jsx +1338 -0
  83. package/src/_b_end_runtime/components/Table.tokens.js +147 -0
  84. package/src/_b_end_runtime/components/TablePreview.jsx +599 -0
  85. package/src/_b_end_runtime/components/Tabs.jsx +149 -0
  86. package/src/_b_end_runtime/components/Tabs.tokens.js +102 -0
  87. package/src/_b_end_runtime/components/Tag.jsx +199 -0
  88. package/src/_b_end_runtime/components/Tag.tokens.js +171 -0
  89. package/src/_b_end_runtime/components/TagBar.jsx +1134 -0
  90. package/src/_b_end_runtime/components/TagBar.tokens.js +75 -0
  91. package/src/_b_end_runtime/components/TagGridPreview.jsx +23 -0
  92. package/src/_b_end_runtime/components/TagInput.jsx +382 -0
  93. package/src/_b_end_runtime/components/TagInput.tokens.js +52 -0
  94. package/src/_b_end_runtime/components/TextArea.jsx +363 -0
  95. package/src/_b_end_runtime/components/TextArea.tokens.js +65 -0
  96. package/src/_b_end_runtime/components/TimePicker.jsx +444 -0
  97. package/src/_b_end_runtime/components/TimePicker.tokens.js +77 -0
  98. package/src/_b_end_runtime/components/Toast.jsx +120 -0
  99. package/src/_b_end_runtime/components/Toast.tokens.js +146 -0
  100. package/src/_b_end_runtime/components/Tooltip.jsx +282 -0
  101. package/src/_b_end_runtime/components/Tooltip.tokens.js +48 -0
  102. package/src/_b_end_runtime/components/TooltipPreview.jsx +50 -0
  103. package/src/_b_end_runtime/components/Upload.jsx +455 -0
  104. package/src/_b_end_runtime/components/Upload.tokens.js +47 -0
  105. package/src/_b_end_runtime/components/avatar-assets/avatar-default.png +0 -0
  106. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-1.png +0 -0
  107. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-2.png +0 -0
  108. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-3.png +0 -0
  109. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-4.png +0 -0
  110. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-5.png +0 -0
  111. package/src/_b_end_runtime/components/empty-assets/administrator-1.svg +40 -0
  112. package/src/_b_end_runtime/components/empty-assets/administrator-2.svg +33 -0
  113. package/src/_b_end_runtime/components/empty-assets/construction.svg +33 -0
  114. package/src/_b_end_runtime/components/empty-assets/failure.svg +49 -0
  115. package/src/_b_end_runtime/components/empty-assets/idle.svg +34 -0
  116. package/src/_b_end_runtime/components/empty-assets/no-access.svg +36 -0
  117. package/src/_b_end_runtime/components/empty-assets/no-content.svg +77 -0
  118. package/src/_b_end_runtime/components/empty-assets/no-result.svg +61 -0
  119. package/src/_b_end_runtime/components/empty-assets/not-found.svg +46 -0
  120. package/src/_b_end_runtime/components/empty-assets/success.svg +38 -0
  121. package/src/_b_end_runtime/components/file-type-assets/batch-report.png +0 -0
  122. package/src/_b_end_runtime/components/file-type-assets/catcat.svg +21 -0
  123. package/src/_b_end_runtime/components/file-type-assets/code.png +0 -0
  124. package/src/_b_end_runtime/components/file-type-assets/conversation.png +0 -0
  125. package/src/_b_end_runtime/components/file-type-assets/document.png +0 -0
  126. package/src/_b_end_runtime/components/file-type-assets/feishu-card.png +0 -0
  127. package/src/_b_end_runtime/components/file-type-assets/feishu-sheet.png +0 -0
  128. package/src/_b_end_runtime/components/file-type-assets/feishu.png +0 -0
  129. package/src/_b_end_runtime/components/file-type-assets/image.png +0 -0
  130. package/src/_b_end_runtime/components/file-type-assets/index.js +105 -0
  131. package/src/_b_end_runtime/components/file-type-assets/knowledge.png +0 -0
  132. package/src/_b_end_runtime/components/file-type-assets/pdf.png +0 -0
  133. package/src/_b_end_runtime/components/file-type-assets/pe.png +0 -0
  134. package/src/_b_end_runtime/components/file-type-assets/strategy.png +0 -0
  135. package/src/_b_end_runtime/components/file-type-assets/table.png +0 -0
  136. package/src/_b_end_runtime/components/file-type-assets/webpage.png +0 -0
  137. package/src/_b_end_runtime/components/file-type-assets/xmind.png +0 -0
  138. package/src/_b_end_runtime/components/icons/icon-data.js +12496 -0
  139. package/src/_b_end_runtime/components/nav-bar-assets/bytehi-logo-mark.svg +21 -0
  140. package/src/_b_end_runtime/components/table-assets/avatar.png +0 -0
  141. package/src/_b_end_runtime/components/table-assets/button.png +0 -0
  142. package/src/_b_end_runtime/components/table-assets/icon-chevron-down.png +0 -0
  143. package/src/_b_end_runtime/components/table-cell-assets/avatar.png +0 -0
  144. package/src/_b_end_runtime/components/table-cell-assets/button.png +0 -0
  145. package/src/_b_end_runtime/components/table-cell-assets/checkbox.png +0 -0
  146. package/src/_b_end_runtime/components/table-cell-assets/icon-chevron-right.png +0 -0
  147. package/src/_b_end_runtime/components/table-cell-assets/icon.png +0 -0
  148. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-handle.png +0 -0
  149. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-tree-triangle-right.png +0 -0
  150. package/src/_b_end_runtime/components/table-cell-assets/switch.png +0 -0
  151. package/src/_b_end_runtime/components/tagShared.js +3 -0
  152. package/src/_b_end_runtime/components/team-avatar-assets/chengcheng-murphy.png +0 -0
  153. package/src/_b_end_runtime/components/team-avatar-assets/duan-ran.png +0 -0
  154. package/src/_b_end_runtime/components/team-avatar-assets/guo-zhezhi.png +0 -0
  155. package/src/_b_end_runtime/components/team-avatar-assets/li-siru.png +0 -0
  156. package/src/_b_end_runtime/components/team-avatar-assets/liu-delin.png +0 -0
  157. package/src/_b_end_runtime/components.js +3499 -0
  158. package/src/_b_end_runtime/index.js +9 -0
  159. package/src/_b_end_runtime/page-patterns/BasePageFramePattern.jsx +395 -0
  160. package/src/_b_end_runtime/page-patterns/ChatConversationPattern.jsx +989 -0
  161. package/src/_b_end_runtime/page-patterns/ChatHomePagePattern.jsx +281 -0
  162. package/src/_b_end_runtime/page-patterns/CopilotPagePattern.jsx +380 -0
  163. package/src/_b_end_runtime/page-patterns/CustomerServiceWorkspaceFramePattern.jsx +392 -0
  164. package/src/_b_end_runtime/page-patterns/IMConversationPattern.jsx +590 -0
  165. package/src/_b_end_runtime/page-patterns/McpManagementPage.jsx +237 -0
  166. package/src/_b_end_runtime/page-patterns/StrategyListPage.jsx +189 -0
  167. package/src/_b_end_runtime/page-patterns/TabTopBarListPage.jsx +594 -0
  168. package/src/_b_end_runtime/page-patterns/VariableManagementPage.jsx +87 -0
  169. package/src/_b_end_runtime/page-patterns/pageListShared.jsx +177 -0
  170. package/src/_b_end_runtime/patterns.js +428 -0
  171. package/src/_b_end_runtime/preview-registry.jsx +4719 -0
  172. package/src/_b_end_runtime/teamMembers.js +56 -0
  173. package/src/_b_end_runtime/tokens.js +500 -0
  174. package/src/index.d.ts +1073 -0
  175. package/src/index.js +52 -0
  176. package/theme.css +350 -0
@@ -0,0 +1,599 @@
1
+ import { useEffect, useMemo, useState } from 'react';
2
+ import Table from './Table';
3
+ import creatorAvatarSrc from './table-assets/avatar.png';
4
+ import { TEAM_MEMBERS } from '../teamMembers';
5
+
6
+ export const TABLE_COLUMN_TYPE_OPTIONS = [
7
+ { id: 'link', label: '可点文本' },
8
+ { id: 'text', label: '文本内容' },
9
+ { id: 'iconText', label: '图标+文本' },
10
+ { id: 'textButton', label: '文本+按钮' },
11
+ { id: 'status', label: '状态' },
12
+ { id: 'tag', label: '标签' },
13
+ { id: 'switch', label: '开关' },
14
+ { id: 'checkbox', label: '复选框' },
15
+ { id: 'avatar', label: '头像' },
16
+ { id: 'avatarText', label: '头像+主副文本' },
17
+ { id: 'linkDescription', label: '可点标题+描述' },
18
+ { id: 'image', label: '图片' },
19
+ { id: 'progress', label: '进度条' },
20
+ { id: 'datetime', label: '日期' },
21
+ { id: 'actions', label: '操作' },
22
+ { id: 'dragHandle', label: '拖拽操作' },
23
+ ];
24
+
25
+ export const TABLE_CELL_SIZE_OPTIONS = [
26
+ { id: 'default', label: '默认' },
27
+ { id: 'middle', label: '中' },
28
+ { id: 'small', label: '小' },
29
+ ];
30
+
31
+ export const TABLE_VARIANT_OPTIONS = [
32
+ { id: 'table', label: '标准表格' },
33
+ { id: 'card-form', label: '卡片型表单' },
34
+ ];
35
+
36
+ const TYPE_LABEL_MAP = Object.fromEntries(TABLE_COLUMN_TYPE_OPTIONS.map((item) => [item.id, item.label]));
37
+
38
+ const TYPE_WIDTH_MAP = {
39
+ link: 188,
40
+ text: 162,
41
+ iconText: 176,
42
+ textButton: 186,
43
+ status: 130,
44
+ tag: 112,
45
+ switch: 108,
46
+ checkbox: 72,
47
+ avatar: 168,
48
+ avatarText: 220,
49
+ linkDescription: 220,
50
+ image: 132,
51
+ progress: 164,
52
+ datetime: 180,
53
+ actions: 152,
54
+ dragHandle: 68,
55
+ };
56
+
57
+ const COLUMN_DEFAULT_TYPES = ['link', 'tag', 'text', 'avatar', 'datetime', 'actions'];
58
+
59
+ const LINK_VALUES = [
60
+ { label: '春季团购套餐上新计划' },
61
+ { label: '门店直播爆款引流活动配置' },
62
+ { label: '周末双人餐核销补贴方案' },
63
+ { label: '连锁门店节假日预约承接排期' },
64
+ { label: '到店美发次卡新客拉新测试' },
65
+ { label: '本地推联投商家素材提审' },
66
+ ];
67
+
68
+ const ICON_TEXT_VALUES = [
69
+ { label: '平台推荐资源位', iconName: 'award-01-stroked' },
70
+ { label: '重点商家扶持计划', iconName: 'award-01-stroked' },
71
+ { label: '高潜团购商品池', iconName: 'award-01-stroked' },
72
+ { label: '履约体验加分项', iconName: 'award-01-stroked' },
73
+ ];
74
+
75
+ const TEXT_BUTTON_VALUES = [
76
+ { label: '补充门店活动亮点说明', iconName: 'edit-04-stroked' },
77
+ { label: '核销动线需补充商场停车指引与到店路径说明', iconName: 'edit-04-stroked' },
78
+ { label: '商家要求新增达人探店口播重点', iconName: 'edit-04-stroked' },
79
+ { label: '预约服务已同步节假日接待上限', iconName: 'edit-04-stroked' },
80
+ ];
81
+
82
+ const STATUS_VALUES = [
83
+ { label: '生效中', tone: 'success' },
84
+ { label: '待上线', tone: 'warning' },
85
+ { label: '已停用', tone: 'danger' },
86
+ { label: '审核中', tone: 'warning' },
87
+ ];
88
+
89
+ const TAG_VALUES = [
90
+ [{ label: '到店餐饮', variant: 'white' }],
91
+ [{ label: '周末热卖', variant: 'white' }],
92
+ [{ label: '新客引流', variant: 'white' }],
93
+ [{ label: '品牌连锁', variant: 'white' }],
94
+ [{ label: '限时抢购', variant: 'white' }],
95
+ [{ label: '达人合作', variant: 'white' }],
96
+ ];
97
+
98
+ const TEXT_VALUES = [
99
+ '适用于商家主页、短视频挂载和同城频道分发。',
100
+ '门店营业时段已同步,支持预约到店与即时核销。',
101
+ '优先投放给近 7 天有团购浏览和收藏行为的高意向用户。',
102
+ '商家补充了停车权益、包间规则和节假日使用说明,文案相对更长一些。',
103
+ '支持多门店联动上架,券后价格已与 POS 系统完成校验。',
104
+ ];
105
+
106
+ const AVATAR_VALUES = TEAM_MEMBERS.map((member) => ({
107
+ name: member.name,
108
+ avatarSrc: member.avatarSrc,
109
+ }));
110
+
111
+ const AVATAR_TEXT_VALUES = [
112
+ { description: '商家运营负责人' },
113
+ { description: '服务商投放经理' },
114
+ { description: '生活服务审核同学' },
115
+ { description: '连锁品牌区域运营' },
116
+ { description: '履约体验项目 owner' },
117
+ { description: '策略分析负责人' },
118
+ { description: '交互设计负责人' },
119
+ { description: '业务架构负责人' },
120
+ { description: '体验优化负责人' },
121
+ ].map((item, index) => ({
122
+ name: TEAM_MEMBERS[index % TEAM_MEMBERS.length].name,
123
+ avatarSrc: TEAM_MEMBERS[index % TEAM_MEMBERS.length].avatarSrc,
124
+ description: item.description,
125
+ }));
126
+
127
+ const LINK_DESCRIPTION_VALUES = [
128
+ { label: '五一爆款双人餐商家联合活动', description: '覆盖 32 家核心门店,预计带动节前搜索与下单转化。' },
129
+ { label: '达人探店合作商家池', description: '待确认到店拍摄时间、素材共创方向及挂载商品组合。' },
130
+ { label: '门店预约服务承接方案', description: '需要同步理发师排班、用户爽约规则和售后处理口径。' },
131
+ { label: '酒旅周边游限时套餐', description: '当前库存充足,但节假日房态需按城市维度单独校验。' },
132
+ ];
133
+
134
+ const DATETIME_VALUES = [
135
+ '2026-04-21 10:30:00',
136
+ '2026-04-20 18:45:00',
137
+ '2026-04-19 14:12:00',
138
+ '2026-04-18 09:20:00',
139
+ '2026-04-17 16:05:00',
140
+ ];
141
+
142
+ const PROGRESS_VALUES = [18, 36, 52, 68, 84, 96];
143
+
144
+ const CARD_FORM_SAMPLE_DATA = [
145
+ {
146
+ id: 'experience-1',
147
+ title: '抖音体验与服务-账号绑定进线流程',
148
+ status: '线上生效',
149
+ subtitle: '用户进线后的路由编排',
150
+ quoteCount: '99+',
151
+ channels: '智能客服、人工坐席',
152
+ description: '面向账号绑定咨询的体验服务流程,负责识别意图、补充信息和转接路径。',
153
+ category: '账号服务',
154
+ updatedAt: '2026-04-21 10:30',
155
+ versions: [
156
+ { id: 'experience-1-v4', v: 4, title: '优化身份校验引导', status: '草稿中', completion: '96%', execCount: 128, satisfaction: '94%', humanRate: '8%' },
157
+ { id: 'experience-1-v3', v: 3, title: '新增绑定失败兜底', status: '实验中', completion: '93%', execCount: 276, satisfaction: '91%', humanRate: '11%' },
158
+ { id: 'experience-1-v2', v: 2, title: '更新账号申诉链路', status: '已发布', completion: '98%', execCount: 512, satisfaction: '95%', humanRate: '7%' },
159
+ ],
160
+ },
161
+ {
162
+ id: 'experience-2',
163
+ title: '抖音体验与服务-创作者权益申诉',
164
+ status: '实验中',
165
+ subtitle: '权益问题自动分流处理',
166
+ quoteCount: '0',
167
+ channels: '在线客服、服务工单',
168
+ description: '用于创作者权益申诉的服务分流,覆盖权益识别、证据补充和工单跟进。',
169
+ category: '权益申诉',
170
+ updatedAt: '2026-04-20 18:45',
171
+ versions: [
172
+ { id: 'experience-2-v2', v: 2, title: '补充权益类型识别', status: '草稿中', completion: '88%', execCount: 74, satisfaction: '89%', humanRate: '15%' },
173
+ { id: 'experience-2-v1', v: 1, title: '上线申诉工单模板', status: '已发布', completion: '92%', execCount: 188, satisfaction: '90%', humanRate: '13%' },
174
+ ],
175
+ },
176
+ {
177
+ id: 'experience-3',
178
+ title: '抖音体验与服务-违规处罚解释',
179
+ status: '暂未生效',
180
+ subtitle: '处罚原因说明与安抚',
181
+ quoteCount: '0',
182
+ channels: '智能客服、人工坐席',
183
+ description: '面向账号处罚咨询,提供处罚原因解释、规则说明和申诉入口引导。',
184
+ category: '账号处罚',
185
+ updatedAt: '2026-04-19 14:12',
186
+ versions: [
187
+ { id: 'experience-3-v3', v: 3, title: '更新处罚解释口径', status: '已发布', completion: '97%', execCount: 342, satisfaction: '93%', humanRate: '9%' },
188
+ { id: 'experience-3-v2', v: 2, title: '增加申诉材料提示', status: '实验中', completion: '90%', execCount: 126, satisfaction: '88%', humanRate: '16%' },
189
+ { id: 'experience-3-v1', v: 1, title: '下线旧版规则说明', status: '已下线', completion: '84%', execCount: 61, satisfaction: '82%', humanRate: '21%' },
190
+ ],
191
+ },
192
+ {
193
+ id: 'experience-4',
194
+ title: '抖音体验与服务-直播间举报处理',
195
+ status: '线上生效',
196
+ subtitle: '举报受理与风险分级',
197
+ quoteCount: '76',
198
+ channels: '在线客服、审核工单',
199
+ description: '用于直播间举报场景的自动受理,支持风险分级、证据收集和处理进度同步。',
200
+ category: '举报处理',
201
+ updatedAt: '2026-04-18 09:20',
202
+ versions: [
203
+ { id: 'experience-4-v2', v: 2, title: '优化高危举报分级', status: '已发布', completion: '95%', execCount: 238, satisfaction: '92%', humanRate: '12%' },
204
+ { id: 'experience-4-v1', v: 1, title: '补充直播证据采集', status: '实验中', completion: '89%', execCount: 105, satisfaction: '87%', humanRate: '18%' },
205
+ ],
206
+ },
207
+ {
208
+ id: 'experience-5',
209
+ title: '抖音体验与服务-订单售后协同',
210
+ status: '草稿中',
211
+ subtitle: '售后咨询与工单协同',
212
+ quoteCount: '32',
213
+ channels: '服务工单、人工坐席',
214
+ description: '面向订单售后咨询,沉淀退款、补偿、进度查询和跨团队协同处理流程。',
215
+ category: '售后协同',
216
+ updatedAt: '2026-04-17 16:05',
217
+ versions: [
218
+ { id: 'experience-5-v2', v: 2, title: '新增补偿协同节点', status: '草稿中', completion: '78%', execCount: 42, satisfaction: '85%', humanRate: '19%' },
219
+ { id: 'experience-5-v1', v: 1, title: '搭建售后查询流程', status: '已发布', completion: '91%', execCount: 214, satisfaction: '90%', humanRate: '14%' },
220
+ ],
221
+ },
222
+ ];
223
+
224
+ const TABLE_PREVIEW_TOTAL = 46;
225
+
226
+ function cloneMockValue(value) {
227
+ if (Array.isArray(value)) {
228
+ return value.map((item) => (typeof item === 'object' && item !== null ? { ...item } : item));
229
+ }
230
+ if (typeof value === 'object' && value !== null) {
231
+ return { ...value };
232
+ }
233
+ return value;
234
+ }
235
+
236
+ function pickMockValue(values, index) {
237
+ return cloneMockValue(values[index % values.length]);
238
+ }
239
+
240
+ function getColumnTitle(type, index) {
241
+ if (type === 'checkbox' || type === 'dragHandle') return '';
242
+ return TYPE_LABEL_MAP[type] || `第${index + 1}列`;
243
+ }
244
+
245
+ function buildCellValue(type, index) {
246
+ switch (type) {
247
+ case 'link':
248
+ return pickMockValue(LINK_VALUES, index);
249
+ case 'iconText':
250
+ return pickMockValue(ICON_TEXT_VALUES, index);
251
+ case 'textButton':
252
+ return pickMockValue(TEXT_BUTTON_VALUES, index);
253
+ case 'status':
254
+ return pickMockValue(STATUS_VALUES, index);
255
+ case 'tag':
256
+ return pickMockValue(TAG_VALUES, index);
257
+ case 'switch':
258
+ return { checked: index % 2 === 0 };
259
+ case 'checkbox':
260
+ return { checked: index % 3 === 0 };
261
+ case 'avatar':
262
+ {
263
+ const avatar = pickMockValue(AVATAR_VALUES, index);
264
+ return {
265
+ name: avatar.name,
266
+ avatarType: 'image',
267
+ avatarSrc: avatar.avatarSrc,
268
+ avatarAlt: `${avatar.name}头像`,
269
+ };
270
+ }
271
+ case 'avatarText':
272
+ {
273
+ const avatarText = pickMockValue(AVATAR_TEXT_VALUES, index);
274
+ return {
275
+ ...avatarText,
276
+ avatarType: 'image',
277
+ avatarSrc: avatarText.avatarSrc,
278
+ avatarAlt: `${avatarText.name}头像`,
279
+ };
280
+ }
281
+ case 'linkDescription':
282
+ return pickMockValue(LINK_DESCRIPTION_VALUES, index);
283
+ case 'image':
284
+ return {
285
+ src: creatorAvatarSrc,
286
+ alt: '生活服务业务配图',
287
+ };
288
+ case 'progress':
289
+ return { value: pickMockValue(PROGRESS_VALUES, index) };
290
+ case 'datetime':
291
+ return pickMockValue(DATETIME_VALUES, index);
292
+ case 'actions':
293
+ return [
294
+ { key: 'edit', label: index % 2 === 0 ? '编辑配置' : '同步门店信息', onClick: () => {} },
295
+ { key: 'view', label: index % 2 === 0 ? '查看详情' : '查看完整方案', onClick: () => {} },
296
+ { key: 'more', kind: 'more', onClick: () => {} },
297
+ ];
298
+ case 'dragHandle':
299
+ return null;
300
+ case 'text':
301
+ default:
302
+ return pickMockValue(TEXT_VALUES, index);
303
+ }
304
+ }
305
+
306
+ function buildActionMessage(actionLabel, rowIndex, columnTitle) {
307
+ return `已点击第 ${rowIndex + 1} 行「${columnTitle || '未命名列'}」的${actionLabel}`;
308
+ }
309
+
310
+ function enhanceCellValue(type, value, { rowIndex, column, setRecords, setInteractionMessage }) {
311
+ const columnTitle = column.title || TYPE_LABEL_MAP[type] || `第${rowIndex + 1}列`;
312
+ const updateCell = (nextValue) => {
313
+ setRecords((prev) => prev.map((row) => (
314
+ row.id === `row-${rowIndex}`
315
+ ? { ...row, [column.dataIndex]: nextValue }
316
+ : row
317
+ )));
318
+ };
319
+
320
+ switch (type) {
321
+ case 'link':
322
+ return {
323
+ ...value,
324
+ onClick: () => setInteractionMessage(buildActionMessage('标题按钮', rowIndex, columnTitle)),
325
+ };
326
+ case 'textButton':
327
+ return {
328
+ ...value,
329
+ onClick: () => setInteractionMessage(buildActionMessage('文本按钮图标', rowIndex, columnTitle)),
330
+ };
331
+ case 'switch':
332
+ return {
333
+ ...value,
334
+ onChange: (checked) => {
335
+ updateCell({ ...value, checked });
336
+ setInteractionMessage(`第 ${rowIndex + 1} 行「${columnTitle}」已切换为${checked ? '开启' : '关闭'}`);
337
+ },
338
+ };
339
+ case 'checkbox':
340
+ return {
341
+ ...value,
342
+ onChange: (checked) => {
343
+ updateCell({ ...value, checked });
344
+ setInteractionMessage(`第 ${rowIndex + 1} 行「${columnTitle}」已${checked ? '勾选' : '取消勾选'}`);
345
+ },
346
+ };
347
+ case 'linkDescription':
348
+ return {
349
+ ...value,
350
+ onClick: () => setInteractionMessage(buildActionMessage('标题+描述按钮', rowIndex, columnTitle)),
351
+ };
352
+ case 'actions':
353
+ return [
354
+ {
355
+ key: 'edit',
356
+ label: '编辑',
357
+ onClick: () => setInteractionMessage(buildActionMessage('编辑', rowIndex, columnTitle)),
358
+ },
359
+ {
360
+ key: 'view',
361
+ label: '查看',
362
+ onClick: () => setInteractionMessage(buildActionMessage('查看', rowIndex, columnTitle)),
363
+ },
364
+ {
365
+ key: 'more',
366
+ kind: 'more',
367
+ onClick: () => setInteractionMessage(buildActionMessage('更多操作', rowIndex, columnTitle)),
368
+ },
369
+ ];
370
+ case 'dragHandle':
371
+ return {
372
+ onClick: () => setInteractionMessage(buildActionMessage('拖拽操作', rowIndex, columnTitle)),
373
+ };
374
+ default:
375
+ return value;
376
+ }
377
+ }
378
+
379
+ function buildColumns(controlValues) {
380
+ const tableSize = controlValues.tableSize || 'default';
381
+ const headerCount = Math.max(2, Math.min(6, Number(controlValues.headerCount || 6)));
382
+ return Array.from({ length: headerCount }, (_, index) => {
383
+ const type = controlValues[`column${index + 1}Type`] || COLUMN_DEFAULT_TYPES[index] || 'text';
384
+
385
+ return {
386
+ key: `column-${index + 1}`,
387
+ title: getColumnTitle(type, index),
388
+ type,
389
+ cellSize: tableSize,
390
+ dataIndex: `column${index + 1}`,
391
+ width: TYPE_WIDTH_MAP[type] || 160,
392
+ };
393
+ });
394
+ }
395
+
396
+ function buildRow(index, columns) {
397
+ const row = { id: `row-${index}` };
398
+ columns.forEach((column, columnIndex) => {
399
+ row[column.dataIndex] = buildCellValue(column.type, index + columnIndex);
400
+ });
401
+ return row;
402
+ }
403
+
404
+ export function buildTableUsageFromControls(controlValues = {}) {
405
+ const tableVariant = controlValues.tableVariant || 'table';
406
+
407
+ if (tableVariant === 'card-form') {
408
+ return [
409
+ `import Table from './components/Table';`,
410
+ '',
411
+ 'const dataSource = [',
412
+ ' {',
413
+ " id: 'experience-1',",
414
+ " title: '抖音体验与服务-账号绑定进线流程',",
415
+ " status: '线上生效',",
416
+ " subtitle: '用户进线后的路由编排',",
417
+ " quoteCount: '99+',",
418
+ " channels: '智能客服、人工坐席',",
419
+ " description: '面向账号绑定咨询的体验服务流程,负责识别意图、补充信息和转接路径。',",
420
+ " category: '账号服务',",
421
+ " updatedAt: '2026-04-21 10:30',",
422
+ ' versions: [',
423
+ " { id: 'experience-1-v4', v: 4, title: '优化身份校验引导', status: '草稿中', completion: '96%', execCount: 128, satisfaction: '94%', humanRate: '8%' },",
424
+ " { id: 'experience-1-v3', v: 3, title: '新增绑定失败兜底', status: '实验中', completion: '93%', execCount: 276, satisfaction: '91%', humanRate: '11%' },",
425
+ ' ],',
426
+ ' },',
427
+ '];',
428
+ '',
429
+ '<Table',
430
+ ' variant="card-form"',
431
+ ' dataSource={dataSource}',
432
+ ' rowKey="id"',
433
+ ' defaultExpandedRowKeys={["experience-1"]}',
434
+ ' pagination={{ current: 1, pageSize: 20, total: dataSource.length, pageSizeOptions: [10, 20] }}',
435
+ ' onExpandedRowKeysChange={(keys) => {}}',
436
+ ' onView={(record, context) => {}}',
437
+ ' onMore={(record, context) => {}}',
438
+ '/>',
439
+ ].join('\n');
440
+ }
441
+
442
+ const columns = buildColumns(controlValues);
443
+ const fixedColumnsMode = controlValues.fixedColumnsMode || 'none';
444
+ const lines = [
445
+ `import Table from './components/Table';`,
446
+ '',
447
+ 'const columns = [',
448
+ ];
449
+
450
+ columns.forEach((column) => {
451
+ lines.push(
452
+ ` { key: '${column.key}', title: '${column.title}', type: '${column.type}', cellSize: '${column.cellSize}', dataIndex: '${column.dataIndex}', width: ${column.width} },`,
453
+ );
454
+ });
455
+
456
+ lines.push('];', '', 'const dataSource = [', ' {');
457
+ columns.forEach((column) => {
458
+ lines.push(` ${column.dataIndex}: /* ${TYPE_LABEL_MAP[column.type] || column.type} 对应数据 */ null,`);
459
+ });
460
+ lines.push(
461
+ ' },',
462
+ '];',
463
+ '',
464
+ '<Table',
465
+ ' columns={columns}',
466
+ ' dataSource={dataSource}',
467
+ ` fixedColumnsMode="${fixedColumnsMode}"`,
468
+ ' pagination={{ current: 1, pageSize: 20, total: dataSource.length, pageSizeOptions: [10, 20] }}',
469
+ '/>',
470
+ );
471
+ return lines.join('\n');
472
+ }
473
+
474
+ export default function TablePreview({
475
+ tableVariant = 'table',
476
+ paginationMode = 'on',
477
+ pageSizeMode = '20',
478
+ tableSize = 'default',
479
+ fixedColumnsMode = 'none',
480
+ headerCount = '5',
481
+ column1Type = 'link',
482
+ column2Type = 'tag',
483
+ column3Type = 'text',
484
+ column4Type = 'avatar',
485
+ column5Type = 'datetime',
486
+ column6Type = 'actions',
487
+ }) {
488
+ const showPagination = paginationMode !== 'off';
489
+ const pageSize = pageSizeMode === '10' ? 10 : 20;
490
+ const controlValues = {
491
+ tableVariant,
492
+ tableSize,
493
+ fixedColumnsMode,
494
+ headerCount,
495
+ column1Type,
496
+ column2Type,
497
+ column3Type,
498
+ column4Type,
499
+ column5Type,
500
+ column6Type,
501
+ };
502
+
503
+ const columns = useMemo(
504
+ () => buildColumns(controlValues),
505
+ [tableSize, fixedColumnsMode, headerCount, column1Type, column2Type, column3Type, column4Type, column5Type, column6Type],
506
+ );
507
+ const [current, setCurrent] = useState(1);
508
+ const [currentPageSize, setCurrentPageSize] = useState(pageSize);
509
+ const [, setInteractionMessage] = useState('点击表格中的按钮、开关或复选框以查看真实交互反馈');
510
+ const [records, setRecords] = useState([]);
511
+ const [expandedRowKeys, setExpandedRowKeys] = useState(['strategy-1']);
512
+
513
+ useEffect(() => {
514
+ setCurrentPageSize(pageSize);
515
+ setCurrent(1);
516
+ }, [pageSize]);
517
+
518
+ useEffect(() => {
519
+ setRecords(Array.from({ length: showPagination ? TABLE_PREVIEW_TOTAL : 10 }, (_, i) => buildRow(i, columns)));
520
+ }, [columns, showPagination]);
521
+
522
+ const dataSource = useMemo(
523
+ () => records.map((record, rowIndex) => {
524
+ const nextRecord = { id: record.id };
525
+ columns.forEach((column) => {
526
+ nextRecord[column.dataIndex] = enhanceCellValue(column.type, record[column.dataIndex], {
527
+ rowIndex,
528
+ column,
529
+ setRecords,
530
+ setInteractionMessage,
531
+ });
532
+ });
533
+ return nextRecord;
534
+ }),
535
+ [columns, records],
536
+ );
537
+
538
+ if (tableVariant === 'card-form') {
539
+ return (
540
+ <div className="flex h-full min-h-0 w-full">
541
+ <Table
542
+ variant="card-form"
543
+ className="h-full"
544
+ dataSource={CARD_FORM_SAMPLE_DATA}
545
+ rowKey="id"
546
+ expandedRowKeys={expandedRowKeys}
547
+ onExpandedRowKeysChange={setExpandedRowKeys}
548
+ pagination={
549
+ showPagination
550
+ ? {
551
+ current,
552
+ pageSize: currentPageSize,
553
+ total: CARD_FORM_SAMPLE_DATA.length,
554
+ pageSizeOptions: [10, 20],
555
+ }
556
+ : null
557
+ }
558
+ onPageChange={(page) => setCurrent(page)}
559
+ onPageSizeChange={(nextPageSize) => {
560
+ setCurrentPageSize(nextPageSize);
561
+ setCurrent(1);
562
+ }}
563
+ onView={(record, context) => {
564
+ setInteractionMessage(`已查看${context.type === 'version' ? '版本' : '策略'}「${record.title}」`);
565
+ }}
566
+ onMore={(record, context) => {
567
+ setInteractionMessage(`已打开${context.type === 'version' ? '版本' : '策略'}「${record.title}」更多操作`);
568
+ }}
569
+ />
570
+ </div>
571
+ );
572
+ }
573
+
574
+ return (
575
+ <div className="flex h-full min-h-0 w-full">
576
+ <Table
577
+ className="h-full"
578
+ columns={columns}
579
+ dataSource={dataSource}
580
+ fixedColumnsMode={fixedColumnsMode}
581
+ pagination={
582
+ showPagination
583
+ ? {
584
+ current,
585
+ pageSize: currentPageSize,
586
+ total: dataSource.length,
587
+ pageSizeOptions: [10, 20],
588
+ }
589
+ : null
590
+ }
591
+ onPageChange={(page) => setCurrent(page)}
592
+ onPageSizeChange={(nextPageSize) => {
593
+ setCurrentPageSize(nextPageSize);
594
+ setCurrent(1);
595
+ }}
596
+ />
597
+ </div>
598
+ );
599
+ }