@doubao-apps/ai 0.0.26 → 0.0.27

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 (91) hide show
  1. package/README.md +21 -0
  2. package/dist/994.js +3 -3
  3. package/dist/contexts/doubao-apps-dev/.ai/examples/common-patterns.md +600 -0
  4. package/dist/contexts/doubao-apps-dev/.ai/examples/component-basics.md +509 -0
  5. package/dist/contexts/doubao-apps-dev/.ai/guides/best-practices.md +571 -0
  6. package/dist/contexts/doubao-apps-dev/.ai/guides/component-development.md +857 -0
  7. package/dist/contexts/doubao-apps-dev/.ai/guides/performance-optimization.md +404 -0
  8. package/dist/contexts/doubao-apps-dev/.ai/guides/system-prompt.md +331 -0
  9. package/dist/contexts/doubao-apps-dev/.ai/guides/troubleshooting.md +291 -0
  10. package/dist/contexts/doubao-apps-dev/.ai/reference/components-quick-ref.md +103 -0
  11. package/dist/contexts/doubao-apps-dev/.ai/reference/framework-api-quick-ref.md +537 -0
  12. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +699 -0
  13. package/dist/{skills/doubao-apps-dev/.ai/reference/open-api/02-storage.md → contexts/doubao-apps-dev/.ai/reference/open-api/02-/345/255/230/345/202/250.md} +13 -21
  14. package/dist/{skills/doubao-apps-dev/.ai/reference/open-api/03-router.md → contexts/doubao-apps-dev/.ai/reference/open-api/03-/350/267/257/347/224/261.md} +9 -9
  15. package/dist/{skills/doubao-apps-dev/.ai/reference/open-api/04-ui- → contexts/doubao-apps-dev/.ai/reference/open-api/04-/347/225/214/351/235/242-}/344/272/244/344/272/222.md +12 -12
  16. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/05-/347/225/214/351/235/242-/350/276/223/345/205/245.md +42 -0
  17. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/06-/347/275/221/347/273/234.md +148 -0
  18. package/dist/{skills/doubao-apps-dev/.ai/reference/open-api/07-media.md → contexts/doubao-apps-dev/.ai/reference/open-api/07-/345/252/222/344/275/223.md} +8 -8
  19. package/dist/{skills/doubao-apps-dev/.ai/reference/open-api/08-open- → contexts/doubao-apps-dev/.ai/reference/open-api/08-/345/274/200/346/224/276/350/203/275/345/212/233-}/344/270/232/345/212/241/350/203/275/345/212/233.md +83 -14
  20. package/dist/{skills/doubao-apps-dev/.ai/reference/open-api/09-device-bluetooth.md → contexts/doubao-apps-dev/.ai/reference/open-api/09-/350/256/276/345/244/207-/350/223/235/347/211/231.md} +22 -46
  21. package/dist/{skills/doubao-apps-dev/.ai/reference/open-api/10-device-wi-fi.md → contexts/doubao-apps-dev/.ai/reference/open-api/10-/350/256/276/345/244/207-wi-fi.md} +9 -9
  22. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/11-/350/256/276/345/244/207-/345/212/240/351/200/237/345/272/246/350/256/241.md +104 -0
  23. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/12-/350/256/276/345/244/207-ibeacon.md +148 -0
  24. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/13-/350/256/276/345/244/207-/347/275/227/347/233/230.md +82 -0
  25. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/14-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +70 -0
  26. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/15-/350/256/276/345/244/207-/351/231/200/350/236/272/344/273/252.md +104 -0
  27. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/16-ui-/350/276/223/345/205/245.md +65 -0
  28. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/17-/350/256/276/345/244/207-/347/275/221/347/273/234.md +164 -0
  29. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/18-/350/256/276/345/244/207-/347/237/255/344/277/241.md +62 -0
  30. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/19-/350/256/276/345/244/207-/346/227/240/351/232/234/347/242/215.md +43 -0
  31. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/20-/350/256/276/345/244/207-/347/224/265/346/261/240.md +83 -0
  32. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/21-/350/256/276/345/244/207-/346/227/245/345/216/206.md +215 -0
  33. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/22-/350/256/276/345/244/207-/345/211/252/350/264/264/346/235/277.md +70 -0
  34. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/23-/350/256/276/345/244/207-/350/201/224/347/263/273/344/272/272.md +270 -0
  35. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/24-/350/256/276/345/244/207-/345/212/240/345/257/206.md +56 -0
  36. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/25-/350/256/276/345/244/207-/347/224/265/350/257/235.md +41 -0
  37. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/26-/350/256/276/345/244/207-/346/211/253/347/240/201.md +100 -0
  38. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/27-/350/256/276/345/244/207-/345/261/217/345/271/225.md +173 -0
  39. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/28-/350/256/276/345/244/207-/351/234/207/345/212/250.md +66 -0
  40. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/README.md +36 -0
  41. package/dist/contexts/doubao-apps-dev/.ai/reference/open-api.md +326 -0
  42. package/dist/contexts/doubao-apps-dev/.ai/rules/dos-and-donts.md +390 -0
  43. package/dist/{skills → contexts}/doubao-apps-dev/AGENTS.md +54 -31
  44. package/dist/manifest.json +45 -0
  45. package/dist/skills/doubao-apps-dev/.ai/examples/common-patterns.md +53 -43
  46. package/dist/skills/doubao-apps-dev/.ai/examples/component-basics.md +0 -17
  47. package/dist/skills/doubao-apps-dev/.ai/guides/component-development.md +96 -214
  48. package/dist/skills/doubao-apps-dev/.ai/guides/system-prompt.md +14 -14
  49. package/dist/skills/doubao-apps-dev/.ai/reference/framework-api-quick-ref.md +46 -85
  50. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +13 -13
  51. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/02-/345/255/230/345/202/250.md +409 -0
  52. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/03-/350/267/257/347/224/261.md +165 -0
  53. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/04-/347/225/214/351/235/242-/344/272/244/344/272/222.md +432 -0
  54. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/05-/347/225/214/351/235/242-/350/276/223/345/205/245.md +42 -0
  55. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/06-/347/275/221/347/273/234.md +148 -0
  56. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/07-/345/252/222/344/275/223.md +346 -0
  57. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/08-/345/274/200/346/224/276/350/203/275/345/212/233-/344/270/232/345/212/241/350/203/275/345/212/233.md +546 -0
  58. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/09-/350/256/276/345/244/207-/350/223/235/347/211/231.md +961 -0
  59. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/10-/350/256/276/345/244/207-wi-fi.md +277 -0
  60. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/11-/350/256/276/345/244/207-/345/212/240/351/200/237/345/272/246/350/256/241.md +104 -0
  61. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/12-/350/256/276/345/244/207-ibeacon.md +148 -0
  62. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/13-/350/256/276/345/244/207-/347/275/227/347/233/230.md +82 -0
  63. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/14-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +70 -0
  64. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/15-/350/256/276/345/244/207-/351/231/200/350/236/272/344/273/252.md +104 -0
  65. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/16-ui-/350/276/223/345/205/245.md +65 -0
  66. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/17-/350/256/276/345/244/207-/347/275/221/347/273/234.md +164 -0
  67. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/18-/350/256/276/345/244/207-/347/237/255/344/277/241.md +62 -0
  68. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/19-/350/256/276/345/244/207-/346/227/240/351/232/234/347/242/215.md +43 -0
  69. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/20-/350/256/276/345/244/207-/347/224/265/346/261/240.md +83 -0
  70. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/21-/350/256/276/345/244/207-/346/227/245/345/216/206.md +215 -0
  71. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/22-/350/256/276/345/244/207-/345/211/252/350/264/264/346/235/277.md +70 -0
  72. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/23-/350/256/276/345/244/207-/350/201/224/347/263/273/344/272/272.md +270 -0
  73. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/24-/350/256/276/345/244/207-/345/212/240/345/257/206.md +56 -0
  74. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/25-/350/256/276/345/244/207-/347/224/265/350/257/235.md +41 -0
  75. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/26-/350/256/276/345/244/207-/346/211/253/347/240/201.md +100 -0
  76. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/27-/350/256/276/345/244/207-/345/261/217/345/271/225.md +173 -0
  77. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/28-/350/256/276/345/244/207-/351/234/207/345/212/250.md +66 -0
  78. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/README.md +27 -11
  79. package/dist/skills/doubao-apps-dev/.ai/reference/open-api.md +282 -166
  80. package/dist/skills/doubao-apps-dev/.ai/rules/dos-and-donts.md +50 -37
  81. package/dist/skills/doubao-apps-dev/SKILL.md +55 -27
  82. package/dist/skills/douyin-to-doubao/SKILL.md +2 -2
  83. package/dist/skills/h5-to-doubao/SKILL.md +2 -2
  84. package/dist/skills/uniapp-to-doubao/SKILL.md +2 -2
  85. package/dist/skills/weixin-to-doubao/SKILL.md +2 -2
  86. package/package.json +4 -2
  87. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/05-ui-/350/276/223/345/205/245.md +0 -95
  88. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/06-network.md +0 -298
  89. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/11-device-/344/274/240/346/204/237/345/231/250.md +0 -372
  90. package/dist/skills/doubao-apps-dev/.ai/reference/open-api/12-device-/346/234/254/345/234/260/350/203/275/345/212/233.md +0 -1005
  91. /package/dist/{skills → contexts}/doubao-apps-dev/CLAUDE.md +0 -0
@@ -0,0 +1,509 @@
1
+ # 组件基础示例
2
+
3
+ Page(页面)和 Widget(卡片)组件的基础用法对比。
4
+
5
+ ---
6
+
7
+ ## 📋 核心差异
8
+
9
+ | 特性 | Page | Widget |
10
+ |------|------|--------|
11
+ | **使用场景** | 全屏页面、九宫格、浮窗 | 聊天流中的卡片 |
12
+ | **定义方式** | `definePage()` | `defineWidget()` |
13
+ | **输入数据** | URL 参数、页面配置 | AI 生成的结构化数据 |
14
+ | **显示位置** | 独立页面/窗口 | 聊天对话中 |
15
+ | **交互方式** | 完整的页面交互 | 卡片内交互 + 消息发送 |
16
+ | **生命周期** | `onCreated`, `onMounted`, `onShow`, `onHide`, `onDestroy`,`onError` | `onCreated`, `onMounted`, `onShow`, `onHide`, `onDestroy`,`onError`,`onForeground`, `onBackground` |
17
+
18
+ ---
19
+
20
+ ## 🎯 Page 基础示例
21
+
22
+ ### 用户资料页面
23
+
24
+ **文件结构**:
25
+ ```
26
+ src/pages/user-profile/
27
+ ├── index.tsx # 组件逻辑
28
+ └── index.scss # 组件样式
29
+ ```
30
+
31
+ ### index.tsx
32
+
33
+ ```tsx
34
+ import { definePage, useState, useEffect } from '@doubao-apps/framework';
35
+ import './index.scss';
36
+
37
+ interface UserProfile {
38
+ id: string;
39
+ name: string;
40
+ avatar: string;
41
+ email: string;
42
+ stats: {
43
+ posts: number;
44
+ followers: number;
45
+ following: number;
46
+ };
47
+ }
48
+
49
+ function UserProfilePage() {
50
+ const [user, setUser] = useState<UserProfile | null>(null);
51
+ const [loading, setLoading] = useState(true);
52
+ const [error, setError] = useState<string | null>(null);
53
+
54
+ // 数据获取
55
+ const fetchUserProfile = async () => {
56
+ try {
57
+ setLoading(true);
58
+ setError(null);
59
+
60
+ // 模拟 API 请求
61
+ await new Promise(resolve => setTimeout(resolve, 1000));
62
+
63
+ const mockData: UserProfile = {
64
+ id: '12345',
65
+ name: '张三',
66
+ avatar: 'https://via.placeholder.com/150',
67
+ email: 'zhangsan@example.com',
68
+ stats: {
69
+ posts: 42,
70
+ followers: 1234,
71
+ following: 567
72
+ }
73
+ };
74
+
75
+ setUser(mockData);
76
+ } catch (err) {
77
+ setError('加载失败,请重试');
78
+ } finally {
79
+ setLoading(false);
80
+ }
81
+ };
82
+
83
+ // 编辑按钮
84
+ const handleEdit = () => {
85
+ console.log('编辑用户资料');
86
+ };
87
+
88
+ // 渲染
89
+ if (loading) {
90
+ return (
91
+ <view className="profile-container">
92
+ <view className="loading">加载中...</view>
93
+ </view>
94
+ );
95
+ }
96
+
97
+ if (error) {
98
+ return (
99
+ <view className="profile-container">
100
+ <view className="error">{error}</view>
101
+ <button onClick={fetchUserProfile}>重试</button>
102
+ </view>
103
+ );
104
+ }
105
+
106
+ if (!user) {
107
+ return null;
108
+ }
109
+
110
+ return (
111
+ <view className="profile-container">
112
+ {/* 头部 */}
113
+ <view className="profile-header">
114
+ <image className="avatar" src={user.avatar} />
115
+ <text className="name">{user.name}</text>
116
+ <text className="email">{user.email}</text>
117
+ <button className="edit-btn" onClick={handleEdit}>
118
+ 编辑资料
119
+ </button>
120
+ </view>
121
+
122
+ {/* 数据统计 */}
123
+ <view className="profile-stats">
124
+ <view className="stat-item">
125
+ <text className="stat-value">{user.stats.posts}</text>
126
+ <text className="stat-label">帖子</text>
127
+ </view>
128
+ <view className="stat-item">
129
+ <text className="stat-value">{user.stats.followers}</text>
130
+ <text className="stat-label">关注者</text>
131
+ </view>
132
+ <view className="stat-item">
133
+ <text className="stat-value">{user.stats.following}</text>
134
+ <text className="stat-label">关注中</text>
135
+ </view>
136
+ </view>
137
+ </view>
138
+ );
139
+ }
140
+
141
+ export default definePage({
142
+ aiMeta: {
143
+ id: 'user-profile',
144
+ title: '用户资料',
145
+ description: '显示用户个人信息和统计数据'
146
+ },
147
+ onShow() {
148
+ console.log('页面显示');
149
+ },
150
+ onHide() {
151
+ console.log('页面隐藏');
152
+ },
153
+ render() {
154
+ return <UserProfilePage />;
155
+ }
156
+ });
157
+ ```
158
+
159
+ ### index.scss
160
+
161
+ ```scss
162
+ .profile-container {
163
+ padding: 32px;
164
+ background-color: #f5f5f5;
165
+
166
+ .loading,
167
+ .error {
168
+ text-align: center;
169
+ padding: 40px;
170
+ font-size: 28px;
171
+ color: #666;
172
+ }
173
+
174
+ .profile-header {
175
+ background-color: #fff;
176
+ border-radius: 16px;
177
+ padding: 40px;
178
+ text-align: center;
179
+ margin-bottom: 32px;
180
+
181
+ .avatar {
182
+ width: 160px;
183
+ height: 160px;
184
+ border-radius: 80px;
185
+ margin-bottom: 24px;
186
+ }
187
+
188
+ .name {
189
+ font-size: 36px;
190
+ font-weight: bold;
191
+ color: #333;
192
+ margin-bottom: 12px;
193
+ }
194
+
195
+ .email {
196
+ font-size: 28px;
197
+ color: #666;
198
+ margin-bottom: 24px;
199
+ }
200
+
201
+ .edit-btn {
202
+ padding: 16px 48px;
203
+ background-color: #1890ff;
204
+ color: #fff;
205
+ border-radius: 8px;
206
+ font-size: 28px;
207
+ }
208
+ }
209
+
210
+ .profile-stats {
211
+ display: flex;
212
+ justify-content: space-around;
213
+ background-color: #fff;
214
+ border-radius: 16px;
215
+ padding: 32px;
216
+
217
+ .stat-item {
218
+ text-align: center;
219
+
220
+ .stat-value {
221
+ font-size: 36px;
222
+ font-weight: bold;
223
+ color: #333;
224
+ margin-bottom: 8px;
225
+ }
226
+
227
+ .stat-label {
228
+ font-size: 24px;
229
+ color: #999;
230
+ }
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ ---
237
+
238
+ ## 🎴 Widget 基础示例
239
+
240
+ ### 天气卡片
241
+
242
+ **文件结构**:
243
+ ```
244
+ src/widgets/weather-card/
245
+ ├── index.tsx # 组件逻辑
246
+ └── index.scss # 组件样式
247
+ ```
248
+
249
+ ### index.tsx
250
+
251
+ ```tsx
252
+ import { defineWidget, getViewData, useState, useEffect } from '@doubao-apps/framework';
253
+ import './index.scss';
254
+
255
+ interface WeatherData {
256
+ city: string;
257
+ temperature: number;
258
+ condition: string;
259
+ humidity: number;
260
+ windSpeed: number;
261
+ icon: string;
262
+ }
263
+
264
+ interface WeatherWidgetInput {
265
+ city: string;
266
+ }
267
+
268
+ function WeatherCard({ city }: WeatherWidgetInput) {
269
+ const [weather, setWeather] = useState<WeatherData | null>(null);
270
+ const [loading, setLoading] = useState(true);
271
+ const [error, setError] = useState<string | null>(null);
272
+
273
+ // 获取天气数据
274
+ const fetchWeather = async () => {
275
+ try {
276
+ setLoading(true);
277
+ setError(null);
278
+
279
+ // 模拟 API 请求
280
+ await new Promise(resolve => setTimeout(resolve, 800));
281
+
282
+ const mockData: WeatherData = {
283
+ city: city,
284
+ temperature: 22,
285
+ condition: '晴天',
286
+ humidity: 65,
287
+ windSpeed: 12,
288
+ icon: '☀️'
289
+ };
290
+
291
+ setWeather(mockData);
292
+ } catch (err) {
293
+ setError('获取天气失败');
294
+ } finally {
295
+ setLoading(false);
296
+ }
297
+ };
298
+
299
+ useEffect(() => {
300
+ fetchWeather();
301
+ }, [city]);
302
+
303
+ // 刷新按钮
304
+ const handleRefresh = () => {
305
+ fetchWeather();
306
+ };
307
+
308
+ // 渲染
309
+ if (loading) {
310
+ return (
311
+ <view className="weather-card">
312
+ <text className="loading">加载中...</text>
313
+ </view>
314
+ );
315
+ }
316
+
317
+ if (error || !weather) {
318
+ return (
319
+ <view className="weather-card">
320
+ <text className="error">{error || '暂无数据'}</text>
321
+ <button onClick={handleRefresh}>重试</button>
322
+ </view>
323
+ );
324
+ }
325
+
326
+ return (
327
+ <view className="weather-card">
328
+ {/* 头部 */}
329
+ <view className="weather-header">
330
+ <text className="city">{weather.city}</text>
331
+ <button className="refresh-btn" onClick={handleRefresh}>
332
+ 刷新
333
+ </button>
334
+ </view>
335
+
336
+ {/* 主要信息 */}
337
+ <view className="weather-main">
338
+ <text className="icon">{weather.icon}</text>
339
+ <view className="temperature-section">
340
+ <text className="temperature">{weather.temperature}°C</text>
341
+ <text className="condition">{weather.condition}</text>
342
+ </view>
343
+ </view>
344
+
345
+ {/* 详细信息 */}
346
+ <view className="weather-details">
347
+ <view className="detail-item">
348
+ <text className="detail-label">湿度</text>
349
+ <text className="detail-value">{weather.humidity}%</text>
350
+ </view>
351
+ <view className="detail-item">
352
+ <text className="detail-label">风速</text>
353
+ <text className="detail-value">{weather.windSpeed} km/h</text>
354
+ </view>
355
+ </view>
356
+ </view>
357
+ );
358
+ }
359
+
360
+ export default defineWidget({
361
+ onMounted() {
362
+ console.log('卡片挂载');
363
+ },
364
+ onDestroy() {
365
+ console.log('卡片销毁');
366
+ },
367
+ render() {
368
+ const input = getViewData<WeatherWidgetInput>();
369
+ return <WeatherCard city={input.city} />;
370
+ }
371
+ });
372
+ ```
373
+
374
+ ### index.scss
375
+
376
+ ```scss
377
+ .weather-card {
378
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
379
+ border-radius: 16px;
380
+ padding: 32px;
381
+ color: #fff;
382
+
383
+ .loading,
384
+ .error {
385
+ text-align: center;
386
+ padding: 32px;
387
+ font-size: 28px;
388
+ }
389
+
390
+ .weather-header {
391
+ display: flex;
392
+ justify-content: space-between;
393
+ align-items: center;
394
+ margin-bottom: 32px;
395
+
396
+ .city {
397
+ font-size: 32px;
398
+ font-weight: bold;
399
+ }
400
+
401
+ .refresh-btn {
402
+ padding: 12px 24px;
403
+ background-color: rgba(255, 255, 255, 0.2);
404
+ color: #fff;
405
+ border-radius: 8px;
406
+ font-size: 24px;
407
+ }
408
+ }
409
+
410
+ .weather-main {
411
+ display: flex;
412
+ align-items: center;
413
+ margin-bottom: 32px;
414
+
415
+ .icon {
416
+ font-size: 120px;
417
+ margin-right: 32px;
418
+ }
419
+
420
+ .temperature-section {
421
+ .temperature {
422
+ font-size: 72px;
423
+ font-weight: bold;
424
+ margin-bottom: 8px;
425
+ }
426
+
427
+ .condition {
428
+ font-size: 28px;
429
+ opacity: 0.9;
430
+ }
431
+ }
432
+ }
433
+
434
+ .weather-details {
435
+ display: flex;
436
+ justify-content: space-around;
437
+ padding-top: 24px;
438
+ border-top: 1px solid rgba(255, 255, 255, 0.3);
439
+
440
+ .detail-item {
441
+ text-align: center;
442
+
443
+ .detail-label {
444
+ font-size: 24px;
445
+ opacity: 0.8;
446
+ margin-bottom: 8px;
447
+ }
448
+
449
+ .detail-value {
450
+ font-size: 32px;
451
+ font-weight: bold;
452
+ }
453
+ }
454
+ }
455
+ }
456
+ ```
457
+
458
+ ---
459
+
460
+ ## 🔑 关键要点
461
+
462
+ ### Page 开发要点
463
+
464
+ 1. **完整的页面生命周期**
465
+ - `onShow()` - 页面显示时调用
466
+ - `onHide()` - 页面隐藏时调用
467
+ - `onDestroy()` - 页面销毁时调用
468
+
469
+ 2. **页面配置 (aiMeta)**
470
+ - `id` - 页面唯一标识
471
+ - `title` - 页面标题
472
+ - `description` - 页面描述
473
+
474
+ 3. **状态管理**
475
+ - 使用 React Hooks(useState, useEffect)
476
+ - 处理加载、错误、数据状态
477
+
478
+ 4. **用户交互**
479
+ - 按钮点击、表单提交
480
+ - 页面跳转、数据更新
481
+
482
+ ### Widget 开发要点
483
+
484
+ 1. **卡片生命周期**
485
+ - `onShow()` / `onHide()` - 卡片显示/隐藏
486
+ - `onForeground()` / `onBackground()` - 应用前后台切换
487
+ - `onMounted()` / `onDestroy()` - 挂载/销毁
488
+
489
+ 2. **输入数据定义 (input schema)**
490
+ - 使用 JSON Schema 定义输入格式
491
+ - AI 根据 schema 生成结构化数据
492
+ - 必须字段使用 `required` 数组
493
+
494
+ 3. **卡片类型 (boxType)**
495
+ - `inbox` - 普通卡片
496
+ - `full_box` - 全宽卡片
497
+
498
+ 4. **消息交互**
499
+ - 接收 AI 传入的数据
500
+ - 可以发送消息回 Bot
501
+ - 支持卡片内交互
502
+
503
+ ---
504
+
505
+ ## 📚 延伸阅读
506
+
507
+ - **组件开发完整指南** → [../guides/component-development.md](../guides/component-development.md)
508
+ - **常用开发模式** → [./common-patterns.md](./common-patterns.md)
509
+ - **API 参考** → [../reference/framework-api-quick-ref.md](../reference/framework-api-quick-ref.md)